Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


6366 / 13646 ツリー ←次へ | 前へ→

【45603】名前ボックスの表示名とActiveXオブジェクトのオブジェクト名の不一致につ... マンマ 07/1/6(土) 10:16 質問[未読]
【45608】Re:名前ボックスの表示名とActiveXオブジェ... yuu1 07/1/6(土) 15:15 回答[未読]
【45609】Re:名前ボックスの表示名とActiveXオブジェ... マンマ 07/1/6(土) 15:22 お礼[未読]
【45611】Re:名前ボックスの表示名とActiveXオブジェ... ichinose 07/1/6(土) 16:49 発言[未読]

【45603】名前ボックスの表示名とActiveXオブジェ...
質問  マンマ  - 07/1/6(土) 10:16 -

引用なし
パスワード
   はじめまして。マンマと申します。

VBAを使って顧客の売上管理が出来るシステムを作っているのですが。
コーディングしている際にどうしても理解出来ない疑問点が出てきまして、
もし分かる方いらっしゃればご教授願います。

売上一覧の行毎に削除ボタンを置いておりまして、画面上のデータを更新する度に
「削除ボタンを全部削除」→「削除ボタンを再作成」という処理を
行っています。

ボタン作成の流れは以下のようになります。

OLEObjects.Addメソッドを利用してオブジェクトを作成し、作成したオブジェクト
をOLEObjectクラスの変数に代入し、OLEObjectのNAMEプロパティを変更し、その後OLEObjectをCommandButtonクラスの変数に代入し、CommandButtonのNAMEプロパティを変更する。

作成処理は以下のFunctionを利用しています。

Function CreateDeleteButtun(rowNum As Integer, btnName As String)
' 削除ボタンを取得
' rowNum : 行番号
' btnName : ボタン名

  Dim height As Double
  Dim width As Double
  Dim top As Double
  Dim left As Double
  Dim obj As OLEObject
  Dim btn As CommandButton
  
  height = Range("T" & (rowNum) & ":" & "U" & (rowNum)).height
  width = Range("T" & (rowNum) & ":" & "U" & (rowNum)).width
  top = Range("T" & (rowNum) & ":" & "U" & (rowNum)).top
  left = Range("T" & (rowNum) & ":" & "U" & (rowNum)).left

  ' ボタンを作成
  Set obj = Worksheets("売上情報").OLEObjects.Add( _
                ClassType:="Forms.CommandButton.1", _
                Link:=True, _
                DisplayAsIcon:=False, _
                left:=left, _
                top:=top, _
                width:=width, _
                height:=height)
   
  ' ボタン名を設定
  obj.Name = btnName
  
  Set btn = obj.Object

  ' 削除ボタンの属性を設定
  btn.Name = btnName
  btn.Caption = "削除"
  btn.Font = 5

End Function

削除処理は以下のFunctionで行っています。

Function DeleteDeleteButton(btnNo As Integer)
' 削除ボタンを削除
' btnNo : 削除ボタンの番号

  Worksheets("売上情報").OLEObjects("btnDelete" & btnNo).Delete
  
End Function

これらのボタンの作成、削除処理を繰り返すと、
「-2147319764:'Name'メソッドは失敗しました:'ICommandButton'オブジェクト」
というエラーが出てしまいます。またエラーが出ずに処理が行えた場合でも、
名前ボックスの表示名は指定したボタン名になっているが、コントロールのオブジェクト
名はCommandButton1(デフォルト)のままであったりといった不具合が起こっています。

ネットで色々調べていたのですが、OLEオブジェクトのADDオブジェクトを使う際は、
変数がクリアされる、名前ボックスの表示名とコントロールのオブジェクト名
(ソースコード名?)が一致しない等色々な問題が載っていました。
しかし、自分ではどの不具合に当たるの分かりません。
EXCELは2003を使っています。ご教授を宜しくお願いします。

【45608】Re:名前ボックスの表示名とActiveXオブジ...
回答  yuu1  - 07/1/6(土) 15:15 -

引用なし
パスワード
   こんにちは。

>売上一覧の行毎に削除ボタンを置いておりまして、画面上のデータを更新する度に
>「削除ボタンを全部削除」→「削除ボタンを再作成」という処理を
>行っています。

コントロールツールボックスのオブジェクトの不都合については認識されているようですが、
addを繰り返すようなロジックを見直したほうがいいと思います。

ロジックを次のようにされてはどうでしょう。
「削除ボタンを全部非表示に」→「削除ボタンを表示」

削除ボタンはデザインモードで全て作成しておく。
削除ボタンを全部非表示に、ではVisibleプロパティをFalseにする
削除ボタンを表示、では必要なボタンを表示し、位置の設定が必要であれば設定する。

【45609】Re:名前ボックスの表示名とActiveXオブジ...
お礼  マンマ  - 07/1/6(土) 15:22 -

引用なし
パスワード
   こんにちは。早速のご返事ありがとうございます。

ADDを繰り返すロジックはどうしても不具合が起こってしまうものなのですね。
yuu1さんのおっしゃる通り
「削除ボタンを全部非表示に」→「削除ボタンを表示」という方法で、
再度作り直してみようと思います。ありがとうございました。


▼yuu1 さん:
>こんにちは。
>
>>売上一覧の行毎に削除ボタンを置いておりまして、画面上のデータを更新する度に
>>「削除ボタンを全部削除」→「削除ボタンを再作成」という処理を
>>行っています。
>
>コントロールツールボックスのオブジェクトの不都合については認識されているようですが、
>addを繰り返すようなロジックを見直したほうがいいと思います。
>
>ロジックを次のようにされてはどうでしょう。
>「削除ボタンを全部非表示に」→「削除ボタンを表示」
>
>削除ボタンはデザインモードで全て作成しておく。
>削除ボタンを全部非表示に、ではVisibleプロパティをFalseにする
>削除ボタンを表示、では必要なボタンを表示し、位置の設定が必要であれば設定する。

【45611】Re:名前ボックスの表示名とActiveXオブジ...
発言  ichinose  - 07/1/6(土) 16:49 -

引用なし
パスワード
   こんにちは。

>「-2147319764:'Name'メソッドは失敗しました:'ICommandButton'オブジェクト」
>というエラーが出てしまいます。
これは、以下の手順で再現できます。

新規ブック(Sheet1という名前のシートが存在するブック)
の標準モジュールに

'========================================================
Option Explicit
'========================================================

Sub test()
  Call CreateDeleteButtun(1, "btnDelete" & 1)
  Call CreateDeleteButtun(2, "btnDelete" & 1)
  Call DeleteDeleteButton(1)
End Sub
'========================================================

Function CreateDeleteButtun(rowNum As Integer, btnName As String)
' 削除ボタンを取得
' rowNum : 行番号
' btnName : ボタン名

  Dim height As Double
  Dim width As Double
  Dim top As Double
  Dim left As Double
  Dim obj As OLEObject
  Dim btn As MSForms.commandButton
 
  height = Range("T" & (rowNum) & ":" & "U" & (rowNum)).height
  width = Range("T" & (rowNum) & ":" & "U" & (rowNum)).width
  top = Range("T" & (rowNum) & ":" & "U" & (rowNum)).top
  left = Range("T" & (rowNum) & ":" & "U" & (rowNum)).left

  ' ボタンを作成
  Set obj = Worksheets("sheet1").OLEObjects.Add( _
                ClassType:="Forms.CommandButton.1")  ' ボタン名を設定
  With obj
    .left = left
    .top = top
    .width = width
    .height = height
    .Name = btnName
    End With
  Set btn = obj.Object

  ' 削除ボタンの属性を設定
  btn.Name = btnName
  btn.Caption = "削除"
  btn.Font = 5

End Function
'========================================================
Function DeleteDeleteButton(btnNo As Integer)
' 削除ボタンを削除
' btnNo : 削除ボタンの番号

  Worksheets("sheet1").OLEObjects("btnDelete" & btnNo).Delete
 
End Function

というコードで再現できます。

尚、「ツール」---「参照設定」で「Microsoft Forms 2.0 Object Library」
にチェックを入れて下さい。

これらの準備を行った後、
1.プロシジャーtestを実行してください。
  Sheet1の2行目のT列〜U列にかけて、コマンドボタンが作成されます。
2.再度、プロシジャーtestを実行してください。
  「-2147319764:'Name'メソッドは失敗しました:'ICommandButton'オブジェクト」  というエラーが発生し、プログラムは中断してしまいます。
  (尚、デバッグ不可です)。

上記の操作で問題のエラーが再現できます。

エラーは、

CreateDeleteButtunファンクションプロシジャーの

  btn.Name = btnName
 
この箇所で発生していると思われます。
原因として考えられるのは、既に存在しているオブジェクト名を別の
コマンドボタンに命名しようとした事が起因しています。

このようなコードが本来のマンマさんコードでも行われていませんか??


解決策は、もっと仕様をお聞きしなくてははっきりしたこといえませんが、
既に投稿されているような「コントロールの動的な作成を行わない」は
他の問題のことも考えると良いことですね!!

後は。コマンドバー「フォーム」のボタンで代替する方法も考えられます。

この手の問題は、再現できないと意味が無い というのが
私の意見です。よって、解決後ですが、投稿しました。

6366 / 13646 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free