- ベストアンサー
エクセルVBAのオブジェクトのハンドリングについて
一応以下のVBAを作って稼動していますが、もっとスマートな方法はないでしょうか。ご存知の方よろしくお願いもうしあげます。 シートやフォームのボタン・ラベルのキャプション、テキストボックスのテキスト、チェックボタンの値をiniファイルに保存し、次回それを使用するVBAを作りました。 iniファイルの中身は以下ようになっています。 [シート名] CommandButton1.Caption=xxxx Label3.Caption=yyyy TextBox6.Text=zzzz ・ ・ [フォーム名] CommandButton8.Caption=xxxx Label5.Caption=yyyy ・ ・ iniファイル作成時はkeyには"CommandButton1.Caption"、その値にはSheets("シート名").CommandButton1.Captionなどの様に個々のオブジェクトを指定しています。 iniファイル読取時はSelect Case文でkey"CommandButton1.Caption"だったら.CommandButton1.Captionに値をセットするようにしています。 セットする個々のオブジェクト全てに書出し、読取りを行っていますのでとても冗長なVBAの記述になっています。 個々のオブジェクトを指定せずに書き出す方法、及びiniファイルに書かれているオブジェクト名で該当オブジェクトに値を設定する方法が知りたいのです。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
エクセルVBAでAPIが使えたかどうかは不明ですが、 APIの GetPrivateProfileSectionNames GetPrivateProfileSection を使えば、INIファイルの内容を列挙できます。それと Me.Controls("TextBox1").Text こういう表記でオブジェクトを指定が可能です。 これらを使えば実装できるのではないでしょうか:) #APIが使えなかったら申しわけない。
その他の回答 (1)
- KenKen_SP
- ベストアンサー率62% (785/1258)
こんにちは。 オブジェクト名で Object を指定する方法は解決したようですね。 あとは、プロパティー名で Property を設定できれば良さそうですか? CallByName を調べてみて下さい。 CallByName の第一引数に渡す Object は、セクション名とキー名から 既知なはずです。例えば、 > CommandButton1.Caption=xxxx であれば、キー名 CommandButton1.Caption を切り分けたらオブジェクト名 とプロパティー名が拾えますよね。また、セクション名でそのオブジェクト の親オブジェクトが分ります。 > [Sheet1] > CommandButton1.Caption=xxxx > Label3.Caption=yyyy > TextBox6.Text=zzzz とりあえず上記の INI で試してみましたが、Select Case や IF を使わず 値を設定することができましたよ。
お礼
回答ありがとうございます。 CallByNameを使うのに四苦八苦しましたが、こんな具合に使えばいいんですね。 Sub Macro1() Debug.Print CallByName(Sheets("Sheet1").OLEObjects("TextBox1").Object, "Text", VbGet) End Sub
お礼
教えていただいた「Me.Controls」でネットを検索していたら、どうやら解決の糸口が見つかりました。 フォームに対しては.Controls、シートに対しては.OLEObjectsを使えばいいようですね。 こんな感じで作ってやればできそうですね。 Sub Test() Dim myO As OLEObject For Each myO In Sheets("Sheet1").OLEObjects Debug.Print myO.Name If InStr(myO.Name, "TextBox") > 0 Then Debug.Print Sheets("Sheet1").OLEObjects(myO.Name).Object.Text End If If InStr(myO.Name, "CommandButton") > 0 Then Debug.Print Sheets("Sheet1").OLEObjects(myO.Name).Object.Caption End If If InStr(myO.Name, "Label") > 0 Then Debug.Print Sheets("Sheet1").OLEObjects(myO.Name).Object.Caption End If Next End Sub
補足
回答ありがとうございます。 GetPrivateProfileSectionNames、GetPrivateProfileSectionなどのAPIに関しては既に使用しております。 教えていただいた「Me.Controls("TextBox1").Text」を色々トライしてみましたが、Meでしたらフォーム上に記述したVBAのみ、Meの部分をフォーム名に変えた場合、標準モジュールから使えましたが、フォーム上のオブジェクトに対してのみ使えるようで、シート上のものに対してはできないようですね。 今回作ったVBAは1つのフォームだけでなく複数のフォーム及びシート上のオブジェクトの内容及び一部のシートの内容そのものを終了時にiniファイルに保存し、次回開始時にiniファイルから呼出すものです。 したがってこのVBAはThisWorkbook又は標準モジュールに記述することになると思います。(現在はThisWorkbookのWorkbook_Open及びWorkbook_BeforeCloseに記述しております) 教えていただいた「Me.Controls("TextBox1").Text」に相当することをThisWorkbook又は標準モジュール上でフォームだけでなくシートのオブジェクトへの設定をどうやって実現するかを知りたいのです。 よろしくお願い申し上げます。 P.S. このエクセルはホストコンピュータの端末です。 端末ソフトのOCXを参照し端末画面を第一シートに設定しています。 この画面に対する各種コマンドをボタンやラベル、テキストボックスから自動入力できるようになっています。 画面の周りにボタンやラベルを配置していますが、それだけでは足りないので必要に応じてフォームを呼出して使えるようにしています。 第二シート以降は簡易言語のようにコマンド群を記述できるようになっています。 使用する担当者によりコマンドなどをカスタマイズする必要がありますが、管理上本体のコピーを許可せず、本体はサーバー上に書き込み禁止の設定で置き、設定内容を各自のiniファイルに保存させております。