lycheejam's tech log

チラ裏のメモ帳 | プログラミングは苦手、インフラが得意なつもり。

VBA セル結合に対するロック解除操作でエラーが発生する場合の対処

概要

事象

・起動時に[エラーコード:1004][アプリケーション/オブジェクト定義エラー]が発生する

原因

・起動時にロック解除の対象セルがActiveシートに存在しない
かつ
・ロック解除の対象セルが結合セル

業務用ツールなどでエクセルブックを開いたときに自動実行されるAutoOpen()関数(?)を使用している場合が多いと思いますが(私が作成するものはすべて使ってます。)
ユーザーにこちらが想定していない使い方をさせないためにセルにロックを掛けてガチガチに想定以外の操作をさせないようにしています。
その場合に上記のエラーが発生したので備忘録として

office 2016の試用期間が終了したので例のごとく参考画像はございません。

サンプルコード

Sub Auto_Open()
    'シート全体をロック
    ThisWorkbook.Worksheets("Sheet1").Cells.Locked = True
    '指定の結合セルをロック解除
    ThisWorkbook.Worksheets("Sheet1").Range(Cells(1, 1), Cells(1, 10)).Locked = False
End Sub

上記コードのように起動時シート全体をロックしてから
任意の結合セルのロックだけを解除すると言う操作があります。

この場合、前回終了時に別シート(Sheet2とか)に遷移した状態で終了すると
起動時にロック解除対象であるSheet1がアクティブでない為エラーが発生します。

ThisWorkbookで指定しているので全然問題ないように見えるのですが
アクティブでないシートの結合状態が把握できないようです。

対処

対処方法は2つあります。(自分が5分で考えた方法)

1つ目

単純にセルロック/解除操作前に指定のシートをアクティブにしてやる方法

Sub Auto_Open()
    'Sheet1をアクティブシートに
    ThisWorkbook.Worksheets("Sheet1").Activate
    'シート全体をロック
    ThisWorkbook.Worksheets("Sheet1").Cells.Locked = True
    '指定の結合セルをロック解除
    ThisWorkbook.Worksheets("Sheet1").Range(Cells(1, 1), Cells(1, 10)).Locked = False
End Sub

これで起動時、強制的にアクティベートされるためエラーは発生しませんでした。
ですがユーザーの前回終了時の状態を強制的に変えてしまうのはいかがなものかと言うことで

2つ目

アクティブでないシートの状況が把握できないのであれば
対象セルが結合セルであることを明記してやれば
VBAちゃんはちゃんと理解してくれるらしい

Sub Auto_Open()
    'シート全体をロック
    ThisWorkbook.Worksheets("Sheet1").Cells.Locked = True
    '指定の結合セルをロック解除
    ThisWorkbook.Worksheets("Sheet1").Range("A1").MergeArea.Locked = False
End Sub

MergeAreaプロパティで明記してやることによってちゃんとロック解除ができる。
この方法ならば勝手に画面遷移は発生しないので不都合は何もないですね。

雑感

C#の本はちまちまサンプルコードやりながら読んだんですよ
でも、ブログに書く体力がない(サンプルコード考える体力も)
会社でエビデンス貼りしかしてないんですがメンタルすり減ってるので家に帰っても無気力状態と言う・・・