変数の保持と呼び出し方法

このQ&Aのポイント
  • 変数を保持して呼び出す方法や変数が受け継がれない場合の対処法について教えてください。
  • Sub AとSub Bという複数のプロシージャをModule1に配置し、Sub Aで指定したファイルをSub Bで呼び出そうとしていますが、変数が受け継がれません。変数を保持する方法はありますか?
  • シートのセルに変数を保持して呼び出す方法以外に、変数を保持する方法はありますか?
回答を見る
  • ベストアンサー

変数を保持して呼び出す方法

変数を保持する方法 2022/02/10 15:36 変数が受け継がれない 2022/02/10 15:24 sub A(),subB()と複数のプロシージャをModule1に配置。 Sub Aでターゲットファイル(T_File)を指定して Sub Bで同じT_Fileを呼び出そうとしたのですが Subの前に配列は宣言しているのでPrivateのハズなのに 変数が受け継がれません T_Fileが”””となります。 多分、Sub A()が終了した時点で一度マクロが終了して 新たにSub B()を呼び出すので上手く変数が受け継がれないのだと思います。 何処かのシートのセルに変数を保持して呼び出す方法が考えられますが そのほかに変数を保持する方法は有りませんか? (できればシートのセルに保持しない方法があれば教えて下さい。) 以下コード(コードが長いので必要と思われる所だけを記載しています。) ’------------------------------------ Option Explicit Dim dlg As FileDialog Dim T_File As String Sub A() Set dlg = Application.FileDialog(msoFileDialogFilePicker) If dlg.Show = False Then MsgBox "処理はキャンセルされました。" Exit Sub Else End If '指定テキストファイル読み込み T_File = dlg.SelectedItems(1) '(途中のコード省略) If rc = vbNo Then MsgBox "処理を中止します。", vbCritical Exit Sub Else MsgBox "処理が終了しました。", vbInformation End If End Sub Sub B() ’T_File = dlg.SelectedItems(1) Folder_Name = CreateObject("Scripting.FileSystemObject").GetParentFolderName(T_File) End Sub

質問者が選んだベストアンサー

  • ベストアンサー
  • kkkkkm
  • ベストアンサー率65% (1614/2453)
回答No.14

利用した各プロシージャの最後に Set C_Ws = Nothing は入れておいてください。 入れておかないと、一度実行して正常にプロシージャから抜けた後でシート名(コードではなく実際のシート名)を変更した場合、そのまま次のプロシージャを実行するとSetとシート名が違うのにエラーになりません。 Setでシート名ではなくシートのオブジェクト名がSetされるためだと思われます。 シート名で探してオブジェクト名でSetする感じ。 なので Set C_Ws = Nothing で開放しておくと、その後の実行時に新しくSetするのでシート名が違う場合ちゃんとエラーになります。

その他の回答 (13)

  • kkkkkm
  • ベストアンサー率65% (1614/2453)
回答No.13

> 利用した各プロシージャの最後に > Set C_Ws = Nothing > を書く代わりに > > クラスのコードの最後に 代わりではなくて 利用した各プロシージャの最後に Set C_Ws = Nothing としてなおかつ クラスのコードの最後に追加 です。 Private Sub Class_Terminate() は Set C_Ws = Nothing が実行されたときに実行されます。 が、「クラスのコードの最後に」のコードは多分必要は無いと思います。 エラーの原因が分からなかったので、あくまでも念のためだけなので。

NuboChan
質問者

お礼

kkkkkmさん、ありがとうございます。 利用した各プロシージャの最後に「Set C_Ws = Nothing」と クラスのコードの最後に「Private Sub Class_Terminate()」がセットで 利用すること説明してもらって理解できました。 >> 以下のようにSetを省いても1行にしてもコード的には問題ない ? >> Dim dlg As Application.FileDialog(msoFileDialogFilePicker) >書けないのではないでしょうか。 同じように2行を1行にする「Dim C_Ws As New Class1」とは、違うのですね。 どう違うのかは、判りませんがそう言うものだと何となく納得しました。 教えてもらったコードに変更してテストコードでマクロ起動>問題なく最後まで処理できました。 お礼申し上げます。

  • kkkkkm
  • ベストアンサー率65% (1614/2453)
回答No.12

> Set C_Ws = New Class1 > は、「プロシージャの外では無効です。」とエラーになります。 > それを避けるために、 > Dim C_Ws As New Class1 > と1行にまとめたとの事でしょうか ? はいそうです。 > 以下のようにSetを省いても1行にしてもコード的には問題ない ? > Dim dlg As Application.FileDialog(msoFileDialogFilePicker) 書けないのではないでしょうか。 > 標準モジュールのコードの最終部で以下のように開放する必要がありますか ? > Set C_Ws = Nothing なくても大丈夫(終了時に解放されると思います)だと思いますが、念のために Setはプロシージャ外では使えないので、利用した各プロシージャの最後に Set C_Ws = Nothing としておいて クラスのコードの最後に(これは無くても上記を設定しておくと開放はされます) Private Sub Class_Terminate() ' 後始末 Set Ws1 = Nothing Set Ws2 = Nothing Set Ws3 = Nothing End Sub を追加しておいてもいいかもしれません。 プロシージャの最後で開放しても、次にC_Wsが参照されるとSetされるので今回の動作では問題は無いと思います。 ただし、Set C_Ws = Nothingの後でC_Wsの存在を確認する If C_Ws Is Nothing Then 何かの作業 End If では何かの作業は実行されません。 > 上記のコードを標準モジュールにコピペして実行後 > エラーが出ているマクロを再度実行しましたが > 又同じエラーが出ます。 これについては「まっとうな方法かどうかは不明」な部分もあり残念ながら理由が分かりません。

NuboChan
質問者

お礼

kkkkkmさん、何度もありがとうございます。 利用した各プロシージャの最後に Set C_Ws = Nothing を書く代わりに クラスのコードの最後に Private Sub Class_Terminate() ' 後始末 Set Ws1 = Nothing Set Ws2 = Nothing Set Ws3 = Nothing End Sub を書けば良いのですね。 5つ有る各プロシージャの最後にNothingのコードを書くより 一つの場所(クラス)に書いてしまうほうがスマートなような気がしています。 >これについては「まっとうな方法かどうかは不明」な部分もあり残念ながら理由が分かりません。 先に記載しましたように原因は  「DETA」によるシート名の不備が原因なので私のミスが全てです。

  • kkkkkm
  • ベストアンサー率65% (1614/2453)
回答No.11

> 肝心のクラスモジュールでは、 > C_Wsは何処にも出てきません。 Dim C_Ws As New Class1 の原型は Dim C_Ws As Class1 Set C_Ws = New Class1 で Dim dlg As FileDialog Set dlg = Application.FileDialog(msoFileDialogFilePicker) と同じパターンになります。 それを一行に収めた記載方法で、宣言とセットを一度で済ませています。 C_WsをClass1のオブジェクト変数にして、ついでにセットしてね。です。 > C_Ws.Ws3.Activate > インデックスが有効範囲にありません。 これは、実際のシート名とSetしたシート名が違ったりしたら出ると思います。 エラーになる手順をはっきりとは説明できませんが Dim C_Ws As New Class1 一度実行されるとそのClass1の内容を覚えているので、最初の実行時にエラーになってシート名を正しく変更したけどエラーになる、もしくはシート名を変更したのにエラーにならないなどが出るかもしれません。 後者は再現できたのですが、前者を再現することができなかったので前者は無いかもしれません。 ので、テスト中は実行後に変更を加えた時 Sub TestNothing() Set C_Ws = Nothing End Sub 上記のようなコードで一度開放したほうがいいと思います。

NuboChan
質問者

お礼

すいません。 エラー原因が見つからないし シートがおかしくなっていると思い新規に作成している途中で シート名”DATA"すべきを何を思ったのか”DETA"とするミスを犯していました。 "DATA"に変更してSub TestNothing()を行って 最初のマクロで問題のエラー無く最後まで処理出来るのを確認しました。 何度も同じミスで我ながら飽きれてしまいました。

NuboChan
質問者

補足

Dim C_Ws As New Class1 は、 Dim C_Ws As Class1 Set C_Ws = New Class1 と同じ意味だと言うのは、説明で理解できたのですが、 標準モジュールの一番先頭の宣言セクション内で Dim C_Ws As New Class1 の代わりに Dim C_Ws As Class1 Set C_Ws = New Class1 と書いても Set C_Ws = New Class1 は、「プロシージャの外では無効です。」とエラーになります。 それを避けるために、 Dim C_Ws As New Class1 と1行にまとめたとの事でしょうか ? Set C_Ws = New Class1 なら 標準モジュールのコードの最終部で以下のように開放する必要がありますか ? Set C_Ws = Nothing >Dim dlg As FileDialog >Set dlg = Application.FileDialog(msoFileDialogFilePicker) >と同じパターンになります。 以下のようにSetを省いても1行にしてもコード的には問題ない ? Dim dlg As Application.FileDialog(msoFileDialogFilePicker) その場合標準モジュールのコード最終部に以下は必要?必要ない?   Set dlg = Nothing ’--------------------------------- >実際のシート名とSetしたシート名が違ったりしたら出ると思います。 正にそのとうりで 実際のシート名とSetしたシート名が違っていました。 すぐに気づいて同じに修正しました。 >Sub TestNothing() > Set C_Ws = Nothing >End Sub 上記のコードを標準モジュールにコピペして実行後 エラーが出ているマクロを再度実行しましたが 又同じエラーが出ます。

  • kkkkkm
  • ベストアンサー率65% (1614/2453)
回答No.10

> 変数の宣言については以下の解釈でいいのですね。 そうですね、簡単に考えると目線がどこからかだと思います。 プロシージャ側の目線だと Private はプロシージャ内 Public はプロシージャの外を含む (ただしプロシージャ内でPrivate Public宣言はできないので、Private Publicに関してはプロシージャ側の目線は無しだと思います) モジュール側の目線だと Private は宣言したモジュール内 Public は宣言したモジュールの外を含む モジュールの宣言セクション内の宣言は「モジュール側の目線」になると思います。 > 宣言セクションで「Dim C_Ws As New Class1」と宣言 これはそれでOKです。 後は 標準モジュールを作る時と同じ操作で 「挿入」の「クラスモジュール」でクラスモジュールを作成します。 Class1ができます。この名前を変更した場合は Dim C_Ws As New Class1のClass1を変更した名前に合わせてください。 クラスモジュールに Option Explicit Public Ws1 As Worksheet Private Sub Class_Initialize() Set Ws1 = Worksheets("DATA") End Sub とします。 この場合、Ws1がDATAシートだというのが標準モジュールを見ているときに分からない(見えない)ので Dim C_Ws As New Class1の下にコメントで 'Ws1 = Worksheets("DATA") とかしておいた方がいいかもしれません。 あとは、使いたいプロシージャでSet無しで MsgBox C_Ws.Ws1.Range("B1").Value のようにして使えます。 ちなみに、オプションで「自動メンバー表示」にチェックが入っていると、C_Wsの後でドットを打った時に「Ws1」が選択肢として表示されます。 また、ひとつのクラスに2個以上セットすることもできます。 Public Ws1 As Worksheet Public Ws2 As Worksheet Private Sub Class_Initialize() Set Ws1 = Worksheets("DATA") Set Ws2 = Worksheets("Sheet2") End Sub

NuboChan
質問者

お礼

解説を受けて、以下のように理解しました。 クラスモジュールは、全く利用したことが無かったので 最初、解説が良く判りませんでしたが何とか今回の件では 利用できる事が出来ました。 1)クラスモジュールを挿入する。 「Class1」のクラスモジュールが作成される (挿入順番で「Class2」などと成るのは標準モジュールと同じ) クラスモジュール(Class1)に以下を追加 Option Explicit Public Ws1 As Worksheet Public Ws2 As Worksheet Public Ws3 As Worksheet Private Sub Class_Initialize() Set Ws1 = Worksheets("DATA") Set Ws2 = Worksheets("Chapter") Set Ws3 = Worksheets("単独型を集計型へ") End Sub 2)標準モジュールの最初の宣言セクションで Dim C_Ws As New Class1 'Set Ws1 = Worksheets("DATA") by Class_Module 'Set Ws2 = Worksheets("Chapter") by Class_Module 'Set Ws1 = Worksheets("単独型を集計型へ") by Class_Module この時、標準モジュールとクラスモジュールではモジュールが違うので 「Dim C_Ws As New Class1」と宣言の下にクラスモジュールでの宣言を コメントで記載したほうが判りやすい。 Dim C_Ws As New xxxx のXXXXは、 クラスモジュールの「Class1」,「Class2」の名前と合わせる。 3)Sub A()などで利用するには、 MsgBox C_Ws.Ws1.Range("B1").Value などと 「Ws1.Range("B1").Value」の前に「C_Ws.」を付加する。 (改めて「SET Ws1=Worksheets("DATA")」 の記述は必要ない) ’-------------------------------- で不思議に思ったのは、 標準モジュールで「Dim C_Ws As New Class1」は C_Wsはクラスモジュール(Class1)で宣言されてますの意味だと思いますが 肝心のクラスモジュールでは、 C_Wsは何処にも出てきません。 (Ws1,Ws2,Ws3はありますが、C_Wsはありません。) これは、どう考えたら良いのでしょうか ?

NuboChan
質問者

補足

すいません。 ’ Set Ws1 = Worksheets("単独型を集計型へ") by Class_Module は、 ’ Set Ws3 = Worksheets("単独型を集計型へ") by Class_Module の間違いです。 上手く処理できそうなので実際にマクロを書き換えて動かしてみました。 しかし、  早速、エラーが出ました。 C_Ws.Ws3.Activate インデックスが有効範囲にありません。

  • kkkkkm
  • ベストアンサー率65% (1614/2453)
回答No.9

> 、Publicのように1回登録すれば > 同じモジュールで利用できるようになりませんか? クラスを使えばできますが、まっとうな方法かどうかは不明です…。 あと、変数宣言と同時にNewするのはいかがなものかで意見が分かれてたりします。 標準モジュールなど Option Explicit Dim C_Ws As New Class1 Sub Test() MsgBox C_Ws.Ws1.Range("A1").Value End Sub Sub Test2() MsgBox C_Ws.Ws1.Range("B1").Value End Sub Class1のコード Class1の名前はプロパティのオブジェクト名で変更できます。 Option Explicit Public Ws1 As Worksheet Private Sub Class_Initialize() Set Ws1 = Worksheets("DATA") End Sub

NuboChan
質問者

お礼

kkkkkmさん、変数の宣言については以下の解釈でいいのですね。 私の認識もまんざら間違いでは無いようです。 モジュールの一番先頭の宣言セクション内に置いて、モジュール レベルの変数を作成することもできます。 ステートメントがモジュールの宣言セクション内にあると、 変数はそのモジュール内のすべてのプロシージャで使用できますが、 プロジェクト内の他のモジュールにあるプロシージャでは使用できません。 モジュール レベルで使用した場合、Dim ステートメントは Private ステートメントと等価です。 コードを読みやすく、解釈しやすくするには、Private ステートメントを使用できます。 この変数をプロジェクト内のすべてのプロシージャで使用可能にするには、 変数の前に Public ステートメントを置きます。 ’----------------------- 宣言セクションでWs1をDIMで宣言して 各プロシジャの複数回必要なSet Ws1 = Worksheets("DATA")を1回で済ませられないかの回答ですが スキル不足で解説された事が理解できないでいます。 つまり、以下の解釈でいいですか ? 宣言セクションで「Dim C_Ws As New Class1」と宣言 Sub A()で「Set Ws1=Worksheets("DATA")」と宣言して 使い時は、ws1の前にC_Ws.を配置して 例えば「MsgBox C_Ws.Ws1.Range("A1").Value」のようにコードを書く。 Sub B()では、同じようにコードを書けば Sub B()で「Set Ws1=Worksheets("DATA")」の宣言は必要ない。

  • kkkkkm
  • ベストアンサー率65% (1614/2453)
回答No.8

> まあ、お勧めはしません。 このあたりは私の回答ではないので… > ミスの元にもなりそうなのでPublicに変更しておきます。 Sub A() の中の Dim T_File As String を削除して正常になったのでしたら、Dimのままでいいと思います。 他のモジュールから参照することが無いのでしたらPublicにすることはないと思いますし、Publicにすると他のモジュールでうっかり同じ変数名で宣言無しで利用したら「あれ?なんか変」な事になるかもしれません。 以下はVBでの説明になっていますがほぼ同じ感覚でいいと思います。 変数を宣言する https://docs.microsoft.com/ja-jp/office/vba/language/concepts/getting-started/declaring-variables

  • kkkkkm
  • ベストアンサー率65% (1614/2453)
回答No.7

と再度宣言してないですね。 以下に訂正 と再度宣言してないですよね。

NuboChan
質問者

お礼

>Sub A() >の中で >Dim T_File As String >と再度宣言してないですね。 >と再度宣言してないですね。 >以下に訂正 >と再度宣言してないですよね。 kkkkkmさん、仰せの通りりの事やっちゃってました。 Option Explicit も外さずに、 DIMもPublicに変更せずに sub A()を削除したら、上手くT_Fileが値が引き継がれました。 >まあ、お勧めはしません。 転ばぬ前の杖、 ミスの元にもなりそうなのでPublicに変更しておきます。

NuboChan
質問者

補足

もうひとつ、疑問点が 以下のようにWs1を定義して Sub A()でSet文でオブジェクトを格納するオブジェクト変数を決めるコードを書いたとして sub B()でも同じSet Ws1 = Worksheets("DATA")を書かないと エラーが出るような気がしますが、Publicのように1回登録すれば 同じモジュールで利用できるようになりませんか? Option Explicit Public Ws1 As Worksheet sub A() Set Ws1 = Worksheets("DATA") End Sub sub B() Set Ws1 = Worksheets("DATA")

  • kkkkkm
  • ベストアンサー率65% (1614/2453)
回答No.6

ふと思ったのですが Sub A() の中で Dim T_File As String と再度宣言してないですね。

  • kkkkkm
  • ベストアンサー率65% (1614/2453)
回答No.5

No.3一部訂正 (Sub A()に宣言が無いのでそのままだとT_Fileの定義が無いというエラーになりますよね) は (Sub A()に宣言が無いのでプロシージャの外での宣言が有効では無い場合、T_Fileの定義が無いというエラーになりますよね)

  • asciiz
  • ベストアンサー率70% (6635/9401)
回答No.4

>DIMで配列宣言をすれば、Public と書かなくても >それは、Publicとして扱われると思っていたのですが >私の認識が間違っているいるのでしょうか? Option Explicit という「厳密に解釈する」オプションがついていますから、グローバル変数(※Microsoftは「パブリック変数」と呼ぶのですね)はきちんとグローバル変数として宣言する必要があります。 >Option Explicit ステートメント (VBA) | Microsoft Docs >https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/option-explicit-statement それを外せば、モジュール外で宣言した変数はすべてグローバル(パブリック)変数になるんじゃないでしょうか。 まあ、お勧めはしません。

関連するQ&A

  • 指定ファイルのみ読み込んで表示する

    現在、以下のコードで指定フォルダー内の全ファイルをA2以下に読み込んでいます。 これでは、処理する必要のないファイルまで読み込まれてしまいます。 (そのため、現在は処理必要ないファイルは手動でA列から削除しています。) Set dlg = Application.FileDialog(msoFileDialogFolderPicker) を Set dlg = Application.FileDialog(msoFileDialogFilePicker) に変更すると ユーザーがファイルを処理が必要なファイルのみ選択できそうですが その場合、どのように変更すれば良いですか ? ’-------------------------------------------------------------- Option Explicit Public dlg As FileDialog Public fol_path As String 'フォルダのフルパス Sub フォルダを指定してファイル名一覧を作成する() Dim f_name As String 'ファイル名 Dim i As Long 'ファイル名を出力する行番号 '書き出しセル初期化 Range("A2:B100").ClearContents 'フォルダを指定するモードでFileDialogを表示 Set dlg = Application.FileDialog(msoFileDialogFolderPicker) '読み込み初期フォルダーの指定 dlg.InitialFileName = "C:\Users\Nubo\Desktop\Temp\" If dlg.Show = False Then MsgBox "処理はキャンセルされました。" Exit Sub Else End If fol_path = dlg.SelectedItems(1) '指定されたフォルダのフルパスを変数に格納 f_name = Dir(fol_path & "\*") 'Dir関数を使って、指定されたフォルダ内の一つ目のファイル名を取得 If f_name = "" Then MsgBox fol_path & " にはファイルが存在しません。" Exit Sub End If 'シートに書き出す Range("C1").Value = fol_path & "のファイル一覧" Range("A1").Value = "現在のファイル名" '見出し行の表示(太字、フォントサイズ 12) With Range("A1:B1") .Font.Bold = True .Font.Size = 12 End With 'A2セルから下にファイル名を書き出し i = 2 Do Until f_name = "" Cells(i, "A").Value = f_name i = i + 1 '次のファイル名を取得 f_name = Dir Loop 'セルの内容に合わせて列幅を自動調整する Range("A:D").EntireColumn.AutoFit MsgBox Sheets("DATA").Name & "にファイル名一覧を作成しました。" & Chr(13) & _ "変名に必要ないファイル名があれば削除してください。" End Sub ’----------------------------------- Office 2021,Windows_11

  • ExcelVBA どこが間違えていますか?

    ExcelVBA 初心者です。 下記のようなプロシージャを人様の作ったのをコピーして作ったのですが意図したとおりになりません。どこが間違っているのか教えてください。 私の意図は選択したフォルダの中の全ファイル(Book)名をアクティブシートのA列に順番に表示したい、です。今は実行すると全部セルA1に表示されてしまって、最後の1つのファイル名しか分かりません。ファイルごとに別のセルに表示したいのです。よろしくお願いします。 Sub ファイル一覧() Dim foldername As String Dim filename As String Dim i As Integer Dim dlg_folder As FileDialog Set dlg_folder = Application.FileDialog(msoFileDialogFolderPicker) Folder_Dialog: dlg_folder.Show If dlg_folder.SelectedItems.Count <> 1 Then Exit Sub Else foldername = dlg_folder.SelectedItems.Item(1) MsgBox "選択したフォルダは " & foldername & " です。" filename = Dir(foldername & "\*.xls", vbNormal) If filename = "" Then MsgBox "Excelファイルがありません。" GoTo Folder_Dialog End If End If Set dlg_folder = Nothing Do While filename <> "" For i = 1 To Workbooks.Count Cells(i, 1).Value = filename i = i + 1 Next i filename = Dir() Loop MsgBox "フォルダ " & foldername & " の中のファイルはすべて表示されました。" End Sub あれ、なぜかインデントが無効になっています。

  • msoFileDialogFolderPicker

    オフィス2003を使っています。 Sub Sample1() With Application.FileDialog(msoFileDialogFolderPicker) If .Show = True Then MsgBox .SelectedItems(1) End If End With End Sub をエクセルの標準モジュールに張り付けるとフォルダを選択するダイアログが開きますが、 アクセスに張り付けると 「msoFileDialogFolderPicker」 の部分が、「変数が定義されていません」となってしまいます。 アクセスでも使えるようにするにはどうすればいいでしょうか?

  • なぜiは変数の値が保持されるのに、wは保持されない

    なぜiは変数の値が保持されるのに、wは保持されないのでしょうか? Sub test() Dim w As Worksheet Dim i As Long i = 1 For Each w In Worksheets i = i + 1 Next MsgBox i MsgBox w.Name End Sub -------------------------------------- を行うと、 MsgBox i は表示されるのに、 MsgBox w.Name は、 「オブジェクト変数または With ブロック変数が設定されていません。」になります。 wはオブジェクト変数だから、 For Each ステートメントを抜けると値が破棄されてしまうのでしょうか? でもvbaのヘルプの 「For Each...Next ステートメントの使い方」 を見ても 「ステートメントを抜けるとオブジェクト変数なら値が破棄されます」 と記載されていません。

  • ACCESS エクスポート ダイアログ ファイル名取得

    ACCESS2003で作成したデータをダイアログで指定したファイル名でエクスポートしたいのですが、上手くできません。 ダイアログが開きその指定したフォルダーにあるエクセルファイルを選択すれば、正常にエキスポートできるのですが、 開いたダイアログにファイル名を入力すると、それ以降動かなくなります。 基本的なことが間違っているのでしょうか?? 詳しい方教えてください。下記にコードした内容を書きました。 よろしくお願いします。 Private Sub cmbTransExcel_Click() On Error GoTo Err_cmbTransExcel_Click Dim fileSaveName As Variant Set dlg = Application.FileDialog(msoFileDialogOpen) With dlg .Title = "チェック" .ButtonName = "エキスポート" .InitialFileName = "C:\Program Files\DATA\" .InitialView = msoFileDialogViewList .AllowMultiSelect = False .Filters.Clear .Filters.Add "xls", "*.xls" End With With dlg If .Show = -1 Then For Each vntPath In dlg.SelectedItems strPath = vntPath Next Else Set dlg = Nothing Exit Sub End If End With Set dlg = Nothing Dim strac As String Dim varxls As Variant Dim strmsg As String strac = "Q_チェック" 'Accessファイルを指定します。 varxls = strPath 'エクセルファイルを指定します。 strmsg = strac & " を、Excelファイルへ出力します。" & Chr(13) & _ "出力先は" & varxls & "、 シート名は" & strac & "です。" & _ Chr(13) & "よろしければ、OKをクリックして下さい。" If MsgBox(strmsg, vbOKCancel) = vbOK Then '最初のデータをフィールド名として使います。 DoCmd.TransferSpreadsheet acExport, _ acSpreadsheetTypeExcel9, strac, varxls, True MsgBox "EXCELの出力が正常終了しました。", vbInformation, "処理終了" End If Exit_cmbTransExcel_click: Exit Sub Err_cmbTransExcel_Click: MsgBox "EXCELの出力が異常終了しました。", vbCritical, "エラー!" Resume Exit_cmbTransExcel_click End Sub

  • iと言う変数の値が1から10の間にないならば

    「iと言う変数の値が1から10の間にないならば」、としたいのですが どのようなコードを書けばいいのでしょうか? Sub test1() Dim i As Integer i = 11 If 1 < i < 10 Then MsgBox i & "は1から10の間にはありません" End If End Sub だと、メッセージが表示されてしまいます。

  • プログラムのイベント処理中断方法

    VB2008のイベンド中止処理についてお教え頂けませんでしょうか。 Formにボタンが1つあり、クリックするとCSVファイルが出力される処理をしたいです。 やりたい処理: 1. 「CSVファイル出力しますか?」というメッセージを出す。YESなら処理続行。Noなら処理中止。 2. CSVファイル出力処理。 3. 「CSVファイルを出力しました。」 (プログラム自体を終了したいわけではありません) VBAだと下記のようなコードを書きたいです。 Sub テスト() Dim ans As Integer ans = MsgBox("CSVファイル出力しますか?", vbYesNo, "テスト") If ans = vbNo Then end end if 'CSV出力処理~~~ end sub VBにendというステートメントがあれば、良いのですが無さそうです・・・ 何か上手な処理はあるでしょうか?VBAのコードになってしまいますが、下記のような処理方法しかないでしょうか? '''''''''''''''''1 Sub テスト() Dim ans As Integer ans = MsgBox("CSVファイル出力しますか?", vbYesNo, "テスト") If ans = vbNo Then end else 'CSV出力処理~~~ end if end sub ''''''''''''''''2 Sub テスト() Dim ans As Integer ans = MsgBox("CSVファイル出力しますか?", vbYesNo, "テスト") If ans = vbNo Then goto here end if 'CSV出力処理~~~ here: end sub

  • VBAでユーザーフォーム上に参照したファイルを開きたいのですが…

    EXCEL2003 SP3での質問です。 ユーザーフォームをVBAで作成中です。 主な機能は、対象月をコンボBOXで選択させた上で、 データ元とインプット先のファイルをテキストBOXに参照し、 実行ボタンクリックでデータ元からインプット先の該当月シートに データをコピーするといった感じです。 (データ元の該当シート内データを全てコピー&ペースト) 取り込み以降の処理はVBAを使用せずに作成しようと考えています。 質問は、取込みたいファイルの参照後の「ファイルを開いてデータをコピーする」処理がうまくいかず、 どのようにしたらよいか教えて頂けますでしょうか。 現在、以下のように記述していますが、 CommandButton3_Click()の部分の処理が分からずファイルが開けません。ご教授ください。 Private Sub CommandButton1_Click() With Application.FileDialog(msoFileDialogFilePicker) .Filters.Clear .Filters.Add "テキスト", "*.csv;*.txt", 1 If .Show = 0 Then Exit Sub Me.TextBox1.Text = .SelectedItems(1) End With End Sub Private Sub CommandButton2_Click() With Application.FileDialog(msoFileDialogFilePicker) .Filters.Clear .Filters.Add "テキスト", "*.csv;*.txt", 1 If .Show = 0 Then Exit Sub Me.TextBox2.Text = .SelectedItems(1) End With End Sub Private Sub CommandButton3_Click() Dim file_name As String If TextBox1.Text = "" Then MsgBox "ファイルが指定されていません", vbInformation ElseIf TextBox1.Text = "" Then file_name = TextBox1.Text = "" Shell "Workbooks.OpenText TextBox1.Value " End If End Sub Private Sub CommandButton4_Click() yesno = MsgBox("保存後、ファイルを閉じます。終了していいですか?", vbYesNo + vbQuestion, "Reportの終了") If yesno = vbYes Then ActiveWorkbook.Save ActiveWorkbook.Close Else End If End Sub

  • フォルダ選択で取得した値を保持する方法

    Excel2007VBA(Vista)を使って、『動画探して一覧表示して選択したら再生出来る自作ソフト』 を作ろうとしています。 分からないのは、以下のコード(処理)で取得出来るフルパスの情報(データ)を 一時的に関数等で保存する方法です。 ※このコードの記述は、 「フォルダを手動で選択後、画面(メッセージボックス)に位置(パス)を表示する」ものです。 With Application.FileDialog(msoFileDialogFolderPicker) 'フォルダを選択する画面を表示する If .Show = True Then 'フォルダを選択後、選択したフォルダがあった時 MsgBox .SelectedItems(1) 'メッセージボックスの画面にパスが表示される End If End With メッセージボックスに出てくる値(パス)を、次に作りたい処理 「フォルダの中にある関係するファイル名を全て一覧で表示する」 の時に使いたいと思っています。 関数の使い分や、オブジェクト型とかの違いが出来ず調べ下手の為、お手上げです! でも絶対完成させたいです。アドバイス宜しくお願いします。

  • 再度,ExcelVBA,public変数が消える

    大変申し訳ありません。一度、この件で質問し、その回答を締め切ったばかりなのですが、やはりもう少し知りたくて質問させていただきます。 ある方の回答への補足で、以下のマクロを具体例としてあげました。ただし、以下のマクロは、時にはpublic変数が消えてしまいますが、しかし、消えないこともあります。 消える理由として、 回答していただいたものから考えて、 1.End Sub を通っていないままに終了しているから 2.不完全なマクロ 3.きちんと作られたマクロの流れ(ルーチン)ではない流れがある 4.「Public 変数は、標準モジュールを経由して、ローカルのUserForm に供給、しかし、それを戻すということはしない。つまり、a.ローカルで発生した値 →標準モジュールのPublic 変数 →UserFormのローカルのプロシージャ b.標準モジュールのPublic 変数 → UserFormのローカルのプロシージャ   ※ただし、起動時の一回きり、それ以上の持ち回しはしない。逆もしない。」この件に関して、以下のマクロに問題がある。 この様なことを考えました。 4.の場合、testMainからtest1.showを呼び出し、a=10とするが、このaの値は、testMainには戻らない(戻らないことがある)のでしょうか、あるいは、testMainのend sub の後は値が保障されないのでしょうか。 あるいは、 Worksheet_SelectionChange でend sub で終わっているので、それ以降は値が保持されないのでしょうか。 あるいは、どこかに欠陥のあるマクロなのでしょうか。 http://okwave.jp/qa/q6420530.html への回答のno.6の例のマクロでendをコメントにするかしないかで、endをコメントにした場合はend subで終わった後、値が保持されています。このこととも合わせて考えると、どこに問題があるのか、どのような問題があるのか、よく分からなくなってしまいます。 よろしくお願いします。 標準モジュールにーーーーーーーーーーーーーーーーー Option Explicit Public a As String Sub ini() MsgBox "初期化します" a = "5" End Sub Sub testMain() If a = "" Then ini MsgBox a test1.Show End Sub test1 というフォームのモジュールにーーーーーーーーーーーーーー (このフォームに コマンドボタンがあります。) Private Sub CommandButton1_Click() a = "10" Unload Me End Sub シートのモジュールにーーーーーーーーーーーーーーーーー Option Explicit Private Sub Worksheet_SelectionChange(ByVal Target As Range) testMain End Sub

専門家に質問してみよう