中断モードでは入力できません とか
ステップ実行は、VBAのコードが何をしているのか、 挙動を確認する事が出来て、デバッグを進める上でとても頼もしい機能です。
しかし「中断モードでは入力できません」と言われて、 ステップ実行が出来なくなる状況に陥る事があります。 この状況に陥ると、どの部分でエラーが発生しているのかを 特定する事が困難になり、コードをロジックで読み解いていくしか方法が無く、 込み入った長いコードであれば、絶望的な気分にさせられたりします。
この状況が発生する条件には、様々な場合があるのかも知れません。 私が知っているのは、 OLEObjects がワークシートに存在する場合です。 OLEObjects というのは旧称で、 今は ActiveX コントロール と呼ぶようです。 でも、VBAでのコーディングでは OLEObjects と指定するのです。
Webページをワークシートに貼り付けたら、意図せずに一緒にActiveXコントロールも 張り付いてしまって、このトラブルに巻き込まれた事があります。 自らワークシートにActiveXコントールを挿入して、何かのツールを作る場合にも このトラブルに巻き込まれる事も普通に考えられます。
再現コード
どういう条件が揃うと、この状況に陥るのかはいろいろあるのだと思います。 ワークシートにActiveXコントロールのチェックボックスを 挿入するコードを書いたら再現できました。
Option Explicit
'標準モジュール
Sub 中断モードでは入力できませんの再現()
Dim ole As OLEObject
Dim chkbx As MSForms.CheckBox
Const cnChkBxName1 As String = "テスト"
Dim ole2 As OLEObject
Dim tgtWS As Worksheet
Set ole = _
Sheet1.OLEObjects.Add( _
ClassType:="Forms.CheckBox.1", _
Left:=10, Top:=10)
Set chkbx = ole.Object
With chkbx
.AutoSize = True
.Caption = cnChkBxName1
End With
ole.Copy
Set tgtWS = Worksheets.Add(After:=Sheet1)
With tgtWS
.Paste
End With
ole.Delete
Set ole2 = tgtWS.OLEObjects(1)
With ole2
.Left = 10
.Top = 10
.Activate
End With
ole2.Activate
End Sub
このコードは、シート1にチェックボックスを 挿入し、挿入したチェックボックスのコピーを 作成したシート2に張り付けて、 シート1に挿入したチェックボックスは削除する、 という事をしています。問題なく動作はします。 しかし、ステップ実行させようとすると ole を Set している行で「中断モードでは入力できません」 と表示され、「続行」するか「終了」するかしか選択肢がなくなります。 この後に続くコード中でエラーが発生していたとしても、エラーの表示はされたとしても、 エラー箇所でコードが中断もされずに、エラー箇所を特定する事が困難な状況に陥ります。
私が知っている回避方法は、OLEObject の存在するワークシートを別ブックに 追い出してから操作する事です。「プロジェクトの管理はブック単位で行われるので」これで うまい事行くのだ、と moug 掲示板の KESUNA さんに教わりました。 当時の掲示板でのやりとりを保存してあった HDD が壊れてしまい、何を説明されたのか 、私にはうまく説明する事が出来ないのですが、だいたいそんな説明でした。 (10年以上前の事です。(*  ̄)遠い目… … )
Option Explicit
'標準モジュール
Public gOleWS As Worksheet
Public gOleWS2 As Worksheet
Sub 中断モードでは入力できませんの回避コード()
Dim ole1 As OLEObject
Dim ole2 As OLEObject
Dim chkbx As MSForms.CheckBox
Const cnName As String = "テスト"
Dim WB As Workbook
Set WB = Workbooks.Add
Set gOleWS = WB.Sheets(1)
Set gOleWS2 = WB.Sheets(2)
'別ブックに貼り付けるOLEObjectであれば
'ステップ実行出来る(中断モードで入力できる)
Set ole1 = _
gOleWS.OLEObjects.Add( _
ClassType:="Forms.CheckBox.1", _
Left:=10, Top:=10)
Set chkbx = ole1.Object
With chkbx
.Caption = cnName
.AutoSize = True
End With
ole1.Copy
With gOleWS2
.Paste
End With
Set ole2 = gOleWS2.OLEObjects(1)
With ole2
.Left = 10
.Top = 10
.Activate
End With
gOleWS2.Copy After:=ThisWorkbook.Worksheets(1)
WB.Close saveChanges:=False
End Sub
結果は全く同じになります。こっちの書き方は全行ステップさせても 問題が起きません。どこかでエラーが発生していれば、その場所で 止まってくれまし、何が起きているのか一行一行観察していく事もできます。
ワークシートにある OLEObject の操作
ところで、ActiveXコントロールのメソッドなりプロパティなりの操作は、 OLEObject に対する操作と、MSFormsのコントロールに対する操作を、 それぞれ 別に指定する、という事が判っていないと、 混乱してコーディングの手が止まってしまいます。
ヘルプには、
ActiveSheet.OLEObjects("CheckBox1").Object.Value = 1
こんなサンプルコードが載っています。 OLEObjects("CheckBox1").Object のObject とは、 MSForms.CheckBox の事なのです。 単に CheckBox と書くと、フォームコントロールの CheckBox をの事になります。 この違いは理解しておく必要があります。 TypeName ではどちらも 'CheckBox' を返すので見分けがつきません。 フォームコントロールのコントロールは、Excelライブラリのコントロールで、 ActiveX コントロールの コントロールは MSForms ライブラリのコントロールです。
要するに、こういう事なのです。
'シートモジュール
Sub sample()
Dim olb As OLEObject
Dim chbx As MSForms.CheckBox
Set olb = _
Me.OLEObjects.Add(ClassType:="Forms.CheckBox.1")
'OLEObjectに対してのプロパティの操作
With olb
.Left = Range("b1").Left + 5
.Top = Range("b1").Top
'設定の保存シート
.LinkedCell = Sheet2.Name & "!a1"
.Name = "sample1"
.ShapeRange.Fill.Transparency = 1# '透明度:透明
Set chbx = .Object
End With
'MSForms.CheckBoxに対してのプロパティの操作
With chbx
.Caption = "sample"
.Font.Size = 12
.ForeColor = RGB(255, 100, 150)
.BackStyle = fmBackStyleTransparent
End With
End Sub
コントロールの操作は、これで判ったとしても、別ブックに追い出したワークシートに あるコントロールの操作は、自ブックのシートにあるコントロールを操作するようにはいきません。
自ブックのシートにあるコントロールは、
Sheet1.chkBx1.Value = True
と書けば素直に参照できるのですが、 別ブックにあるシートの変数である gWS を使って、
gWS.chkBx.Value = True
と、書いても、「メソッドまたはデータ メンバが見つかりません。」という エラーになります。入力候補表示の中にも chkBx は出てきてくれません。
ちょっと不便ではありますが、
Set chkBx = gWS.OLEObjects("chkBx").Object
chkBx.Value = True
とか、
Set chkbx = CallByName(gWS, "chkBx", VbGet)
chkbx.Value = True
とか、書いて凌げます。gWS との紐付けがなくなってしまっている事には 変りなく、沢山のコントロールがあると混乱しそうです。 構造体でも作ってまとめておくと、扱いやすいかもです。
Option Explicit
'標準モジュール
Public gWS As Worksheet
Private Type typWScontrol
chkBx As MSForms.CheckBox
chkBx2 As MSForms.CheckBox
End Type
Sub sample()
'Sheet1にはchkBx と chkBx2 という名前の
'oleコントロールがある。
Sheet1.Copy
Set gWS = ActiveSheet
Dim wsCtrls As typWScontrol
Set wsCtrls.chkBx = gWS.OLEObjects("chkBx1").Object
Set wsCtrls.chkBx2 = gWS.OLEObjects("chkBx2").Object
'wsCtrls. と打てば、ペロンと入力候補が表示されて
'扱いやすくなる。
wsCtrls.chkBx.Value = True
End Sub
以上
« ACCESS VBA レコードセットの件数を数える | トップページ
トラックバック
この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/555928/59500343
この記事へのトラックバック一覧です: 中断モードでは入力できません とか:
コメント