[VBA] この配列は固定されているか、または一時的にロックされています【対処法】

こんにちは。

VBAで配列を操作しているときに、

「この配列は固定されているか、または一時的にロックされています。」

とエラーメッセージが出たことはありませんか?

その場合の対処法を紹介します。

私の場合は、
静的配列を別の関数に渡し、別の関数内で配列の要素数を変更しようとしたこと
が原因でした。

具体的に、どういった場合に起こるのかご紹介します。

  • 動的配列のReDim → OK
  • 静的配列のReDim → エラー
  • 動的配列の宣言後、他の関数内でReDim → OK
  • 静的配列の宣言後、他の関数内でReDim → エラー(表題のエラー)

となります。1つずつ具体例とともに解説します。

ReDimによる配列の要素数の変更

動的配列の場合→OK

Public Sub test()
    
    Dim arr() As String // 動的配列を宣言
    
    ReDim arr(1)
    ReDim arr(2)

End Sub

これは問題なく通ります。
動的配列を宣言したので、配列数を変更しても問題ないです。

静的配列の場合→エラー

Public Sub test()
    
    Dim arr(0) As String
    
    ReDim arr(1) // ここでエラー
    ReDim arr(2)

End Sub

静的配列の要素数を変更しようとするとエラーになりますよね。

エラーメッセージは

「コンパイルエラー:配列は既に宣言されています。」

となります。

配列の宣言部を見直せば、ミスに気がつけるかと思います。

動的配列を他の関数内でReDimする場合→OK

Public Sub test()
    
    Dim arr() As String

    Call funcRedim(arr())

End Sub

Function funcRedim(ByRef arr_() As String)

    ReDim arr_(1)
    ReDim arr_(2)

End Function

これも問題なく動き、arrの配列数が拡張されます。

静的配列を他の関数内でReDimする場合→エラー(表題のエラー)

問題のものです。

Public Sub test()
    
    Dim arr(0) As String // 静的配列

    Call funcRedim(arr())

End Sub

Function funcRedim(ByRef arr_() As String)

    ReDim arr_(1)
    ReDim arr_(2)

End Function

お分かりかと思いますが、エラーになります。静的配列の要素数は変更できません。

ただ、このときのエラーメッセージが

「この配列は固定されているか、または一時的にロックされています」

と出てきます。

“固定された配列を宣言したから、たしかに・・・”と思えばいいですが、

“一時的にロック?!?!いろんなとこで配列使いすぎて操作できなくなった!?!?!?”みたいなパニックに(私はなりました)

といいますか、見たことないメッセージだったので焦りました。静的配列のReDimのエラーでも環境?場所?によってはメッセージが変わるんですね。

まとめ

配列の宣言には気をつけたいです。