- ベストアンサー
エクセル VBAについて
初心者ですが、指導してください。 エクセルでVBA・マクロを使用して見積書を作っています。 AファイルとBファイルを順番に開いた状態で使用します。 Bファイルは見積書のテンプレートファイルになっています。 Bファイルで担当者が新しく見積書を作った場合、 ファイル保存というボタンで、指定のホルダ内に任意のファイル名で保存する事が可能になっています。 新しく保存したファイルをCファイルとします。 Cファイルを修正等する場合は、AファイルからCファイルを読み込みます。 Aファイルは、トップページ兼価格リスト表になっています。 ここで問題というか分からなくなっている部分は、 テンプレートファイルであるBファイルの時は、VBAの記述の際に、 Windows("B.xls").Activate と記載していますが、 任意のファイルであるCファイルの時は、 担当者によって、任意のファイル名で保存されているため ファイル名の取得?が必要になると思います。 その場合、どの様な記述をすればいいのでしょうか? なかなか上手に説明できませんが、よろしくお願いします。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
>自動的に任意ファイルを指定する方法は、わかりますか? 先のも自動的に取得していましたが不満でしょうか? For Each wb In Workbooks If Not (wb.name = "A.xls" Or wb.name = "B.xls") Then name = wb.name Exit For End If Next Windows(name).Activate とすれば、勝手にファイル名を取得して実行してくれます。 転記対象外の予期しないファイルが開いていても実行するので、あまりお勧めしませんが・・・。 (先のも、今回のもエラー処理はしていません。) -------------------------------------------------- 担当者によって、任意のファイル名で保存されているため ファイル名の取得?が必要になると思います。 その場合、どの様な記述をすればいいのでしょうか? -------------------------------------------------- VBAも万能ではありません。 目的の事だけを実行させるのは簡単ですが、正しく処理を終了出来るプログラムを書くことも大切だと思いますよ。 そのためには、ファイルの保存先やファイル名をチェックして実行する方が良いかと思います。 例1)ファイル選択ダイアログからファイルを指定する。 例2)シート上にファイルのリストを用意し、転記対象ファイルをチェックする。 例3)シート上の目印(文字等)をチェックして、実行対象か判断する。 等の処理を行う方が安全かと思います。 (もう少し勉強してから挑戦してみてください。) 先の例では、実行する転記対象ファイルの確認のためにINPUTBOXを使用しました。
その他の回答 (5)
- Wendy02
- ベストアンサー率57% (3570/6232)
#2です。 あまり、私の書いたことには関心を示さなかったようですね。ただ、人の回答は、それなりの考えがあって書いているのですから、分からない場合は、「分からない」という意思表示されたほうが良いです。それで、その説明を求めるかどうかは、また、別問題です。ご質問者さんは、もう三回も書かれているようですから、なるべく、上手な対応したほうが、ここのカテゴリの利用度があがります。 それから、重ねますが、テンプレートとおっしゃるなら、テンプレートファイルにしたほうがよいです。オリジナルを上書きされないし、ファイル名もある程度キメウチできます。 以下のマクロは、私なりに考えてみました。何度、開いても、シートに、「価格統合」「合計見積書」というシートがあれば、シートの名前がセットされます。閉じたら、変数の中は、クリアされますので、クリック等をしても、マクロは働きません。 なお、このマクロは、動作確認できたら、後は、プロジェクトをプロテクトしたほうが良いです。いじると、インスタンスが壊れることがありますから、ブック名が取れなくなります。 'Class1 Public WithEvents App As Application Private Sub App_WorkbookOpen(ByVal Wb As Workbook) Dim wh As Variant Dim chk1 As Boolean Dim chk2 As Boolean chk1 = False: chk2 = False For Each wh In Wb.Worksheets If wh.Name Like "価格統合*" Then chk1 = True ElseIf wh.Name Like "合計見積書*" Then chk2 = True End If Next wh If chk1 And chk2 Then BkName = Wb.Name End If End Sub Private Sub App_WorkbookBeforeClose(ByVal Wb As Workbook, Cancel As Boolean) If Wb.Name = BkName Then BkName = "" End If End Sub '標準モジュール Public BkName As String Public Class1 As Class1 Sub Auto_Open() Call GetInstance End Sub Sub GetInstance() 'インスタンス生成 Set Class1 = New Class1 Set Class1.App = Application End Sub Sub Test1() '実行マクロ If BkName = "" Then Exit Sub Application.Goto Workbooks(BkName).Sheets("価格統合").Range("C3") ActiveSheet.Paste Range("A1").Select Application.Goto Workbooks(BkName).Sheets("合計見積書").Range("A8") End Sub
お礼
すばらしい回答ありがとうございます。 自分なりに色々考え、勉強します。 回答された内容も、拝見させて頂き、参考にしながら進めたいと思っています。 上司の意見で、色々内容も変化するので。。。 ありがとうございました。
- WWolf
- ベストアンサー率26% (51/192)
#1です。 詳細コード(またはフロー)が見えないので言い切れませんが、AのコードにB.xlsを開くコードが記述されていませんでしょうか? その部分にAから開いたブック名を取得し変数に入れ >Windows("C.xls").Activate の"C.xls"の部分を変数にしてやれば取り敢えずはOKだと思いますが? しかしながら、他の回答者さんなども答えているように根本的な部分を考える必要はあります。 よって、B.xlsを開くコードが記述されている場所がわかるならその部分のコードを変形させるか、もしくは他の回答者さんの回答にもある現在開いているブック名を取得し対応するかで、エラーが起こる対処は運用でカバーする事で、目の前の問題は取り敢えず解決すると思われます。
お礼
万能ではないマクロですので、根本的に考える必要はあると思いますが、エクセルで作れ!!という上司の命令ですので、がんばってみます。やり方を考え、自分なりにやってみたいと思います。 ありがとうございました。
- hana-hana3
- ベストアンサー率31% (4940/15541)
>開いているファイルを指定する方法はないでしょうか? こんな感じでいかがでしょうか? [OK] をクリックしたブック名が設定されます。 Dim wb As Workbook Dim name As String For Each wb In Workbooks If Not (wb.name = "A.xls" Or wb.name = "B.xls") Then name = InputBox("個人ブック名", "設定", wb.name) If name <> "" Then Exit For End If Next Windows(name).Activate
補足
Aファイルは必ず開いています。 Cファイルは任意の名前のファイルで開いています。 現在は、Aファイルのモジュール2に下記の記述があります。 あるボタンをクリックすると、下記が動作するようになっています。 Windows("A").Activate Sheets("価格統合").Select Range("C3:D1563").Select Selection.Copy Sheets("見積書スタート").Select Range("A1").Select Windows("C.xls").Activate Sheets("価格統合").Select Range("C3").Select ActiveSheet.Paste Range("A1").Select Sheets("合計見積書").Select Range("A8").Select Windows("C.xls").Activateの部分が、自動的に開いているファイル名にしたいのです。 Aファイルの一部分をCファイル(任意ファイル)にコピーさせたいのですが。。。。 Aファイルは必ず開いてありますが、任意ファイルはCファイルであったり、Dファイルであったりします。 自動的に任意ファイルを指定する方法は、わかりますか? よろしくお願いいたします。
- Wendy02
- ベストアンサー率57% (3570/6232)
こんばんは。 >テンプレートファイルであるBファイルの時は、VBAの記述の際に、 >Windows("B.xls").Activate と記載していますが、 テンプレートでしたら、拡張子は、xlt になっているはずですね。 それと、そのテンプレートの中にあるマクロの、ブックは、ThisWorkbook のではないでしょうか?そうしないと、その中にあるマクロは、ファイル名が変わったら、全滅になってしまうと思います。 >Cファイルを修正等する場合は、AファイルからCファイルを読み込みます。 >担当者によって、任意のファイル名で保存されているため 一旦保存して終了した後に、再度読み込んで、修正すると読みましたが、担当者ごとにあるファイルを、オープンダイアログでファイルを選ばせる時に、カスタムプロパティに書き込むか、パブリック変数に置くかどちらかだと思います。ただし、経験的に、パブリック変数の中は、抜けてしまうことがあります。通常は、再取得するマクロを作るのですが、この場合は、ファイルを特定できませんから、それが出来ません。 まったく任意のファイル名で付けられたら、開いた後、何か特徴でもなければ、ループで検索も出来ないと思います。 >ファイル名の取得?が必要になると思います。 一体、どこで必要になるのか分かりません。ActiveWorkbook とか、ThisWorkbook なら、ファイル名の取得する必要性は少ないです。なお、システムを作ろうとしているなら、VBAが、1~2年ぐらいでは、かなり難しいです。
お礼
ありがとうございました
- WWolf
- ベストアンサー率26% (51/192)
Windows("B.xls").Activateが理解されているなら CファイルをAから読み込んだ時に OPWBN=ActiveWorkbook.Name とでもしてOPWBNを見てください。
補足
下記のように記述しています。 Windows("A").Activate Sheets("価格統合").Select Range("C3:D1563").Select Selection.Copy Sheets("見積書スタート").Select Range("A1").Select Windows("C.xls").Activate Sheets("価格統合").Select Range("C3").Select ActiveSheet.Paste Range("A1").Select Sheets("合計見積書").Select Range("A8").Select 上記でC.xlsファイルが担当者で任意の名前になってしまいます。 Windows("C.xls").Activate ではなく、開いているファイルを指定する方法はないでしょうか?
お礼
色々ありがとうございました。 インプットボックスでは、ファイル名を消す恐れがあるので。。。 教えていただいたものを参考にして、自分なりに勉強してみます。 ありがとうございました。