
vba初心者です。現在同じフォルダ内に同じ形式で従業員の評価点が記載されている複数のシートの情報を抽出して別ブックに転記するプログラムを書いております。ユーザーに参照フォルダと出力先のブックを選択させる方式で、完成したのですがバグがあり完全できません。具体的には
1、参照フォルダにサブフォルダが存在する場合、サブフォルダ内のファイルから情報を抽出できない
2、出力先ブックにマクロ実行しているブックを選択するとファイルを二重に開こうとして止まってしまう
の二点です。
どう書き直せばいいかご教授お願い致します。
以下作成したプログラム
Option Explicit
Dim fpath1 As Variant
Dim fpath2 As Variant
Dim openfilename1 As Variant
Dim openfilename2 As Variant
Dim folder As Object
Dim file As Object
Private Sub CommandButton1_Click()
Set folder = CreateObject("Shell.Application"). _
BrowseForFolder(0, "フォルダを選択してください", 0, "C:¥")
If Not folder Is Nothing Then
参照.Value = folder.self.Path
End If
End Sub
Private Sub CommandButton2_Click()
Dim filename As String
fpath2 = Application.GetOpenFilename(filefilter:="Excelファイル,*.xlsx;*.xlsm;*.xls")
openfilename2 = Dir(fpath2)
出力.Text = fpath2
End Sub
Private Sub CommandButton3_Click()
Const cnsDIR = "\*.xlsx"
Dim strPath As String
Dim strFilename As String
Dim GYO As Long
Dim i As Long
'フォルダの場所指定
strPath = 参照.Value
'先頭のファイル名取得
strFilename = Dir(strPath & cnsDIR, vbNormal)
i = 1
'ファイルが見つからなくなるまで繰り返す
Do While strFilename <> ""
'行を加算
i = i + 1
Workbooks.Open "C:\Users\kairi\Downloads\評価\" & strFilename
ActiveWorkbook.ActiveSheet.Range("J2").Copy
ActiveWorkbook.Close
Workbooks.Open (fpath2)
ActiveWorkbook.ActiveSheet.Cells(i, 1).PasteSpecial
ActiveWorkbook.Close SaveChanges:=True
Workbooks.Open "C:\Users\kairi\Downloads\評価\" & strFilename
ActiveWorkbook.ActiveSheet.Range("D1").Copy
ActiveWorkbook.Close
Workbooks.Open (fpath2)
ActiveWorkbook.ActiveSheet.Cells(i, 2).PasteSpecial
ActiveWorkbook.Close SaveChanges:=True
Workbooks.Open "C:\Users\kairi\Downloads\評価\" & strFilename
ActiveWorkbook.ActiveSheet.Range("K1").Copy
ActiveWorkbook.Close
Workbooks.Open (fpath2)
ActiveWorkbook.ActiveSheet.Cells(i, 3).PasteSpecial
ActiveWorkbook.Close SaveChanges:=True
Workbooks.Open "C:\Users\kairi\Downloads\評価\" & strFilename
ActiveWorkbook.ActiveSheet.Range("M1").Copy
ActiveWorkbook.Close
Workbooks.Open (fpath2)
ActiveWorkbook.ActiveSheet.Cells(i, 4).PasteSpecial
ActiveWorkbook.Close SaveChanges:=True
Workbooks.Open "C:\Users\kairi\Downloads\評価\" & strFilename
ActiveWorkbook.ActiveSheet.Range("O1").Copy
ActiveWorkbook.Close
Workbooks.Open (fpath2)
ActiveWorkbook.ActiveSheet.Cells(i, 5).PasteSpecial
ActiveWorkbook.Close SaveChanges:=True
Workbooks.Open "C:\Users\kairi\Downloads\評価\" & strFilename
ActiveWorkbook.ActiveSheet.Range("L5").Copy
ActiveWorkbook.Close
Workbooks.Open (fpath2)
ActiveWorkbook.ActiveSheet.Cells(i, 6).PasteSpecial
ActiveWorkbook.Close SaveChanges:=True
Workbooks.Open "C:\Users\kairi\Downloads\評価\" & strFilename
ActiveWorkbook.ActiveSheet.Range("L6").Copy
ActiveWorkbook.Close
Workbooks.Open (fpath2)
ActiveWorkbook.ActiveSheet.Cells(i, 7).PasteSpecial
ActiveWorkbook.Close SaveChanges:=True
Workbooks.Open "C:\Users\kairi\Downloads\評価\" & strFilename
ActiveWorkbook.ActiveSheet.Range("L7").Copy
ActiveWorkbook.Close SaveChanges:=True
Workbooks.Open (fpath2)
ActiveWorkbook.ActiveSheet.Cells(i, 8).PasteSpecial
ActiveWorkbook.Close SaveChanges:=True
Workbooks.Open "C:\Users\kairi\Downloads\評価\" & strFilename
ActiveWorkbook.ActiveSheet.Range("L8").Copy
ActiveWorkbook.Close SaveChanges:=True
Workbooks.Open (fpath2)
ActiveWorkbook.ActiveSheet.Cells(i, 9).PasteSpecial
ActiveWorkbook.Close SaveChanges:=True
Workbooks.Open "C:\Users\kairi\Downloads\評価\" & strFilename
ActiveWorkbook.ActiveSheet.Range("L9").Copy
ActiveWorkbook.Close SaveChanges:=True
Workbooks.Open (fpath2)
ActiveWorkbook.ActiveSheet.Cells(i, 10).PasteSpecial
ActiveWorkbook.Close SaveChanges:=True
strFilename = Dir()
Loop
End Sub
A 回答 (3件)
- 最新から表示
- 回答順に表示

No.3
- 回答日時:
Workbooks.Open "C:\Users\kairi\Downloads\評価\" & strFilename
この箇所ですが、
Private Sub CommandButton1_Click()
で取得したフォルダのファイルをオープンするのではないでしょうか。
"C:\Users\kairi\Downloads\評価\" ではなく、「参照.Value」を使用すべきかと思いますが、いかがでしょうか。
No.2
- 回答日時:
最初にマクロの基本。
同じ内容のコードは書かないことなのですが、それも、ここではOpen-Close を繰り返すと、エラーが出そうな気がしてきます。
完全に造りそのものを変えてしまいましたので、評価しにくいとは思いますが、考え方の参考にしてみてください。
>どう書き直せばいいかご教授お願い致します。
造りそのものは、単純で、再帰もアルゴリズムも使っていません。
1.
'UserForm に組み込んではいませんが、フォルダーからのファイル名を検索する方法
'再帰の使い方は知っていますが、あえて辞めました。
なお、開発はUserForm上ではありませんので、いくぶん、甘い部分が残っているかもしれません。
'★の部分がユーザー設定
'//あえてサプルーチンにしてしまいました。その方が失敗が少ないからです。
Sub MakingFileList(Files)
Dim Folders()
Dim Pth As String
Dim i As Long
Dim Defpath As String
Dim n As Long
Defpath = Application.DefaultFilePath 'デフォルトファイルパス ★
ReDim Preserve Folders(0)
If InStrRev(Defpath, "\") = Len(Defpath) Then n = 1
Folders(i) = Left(Defpath, Len(Defpath) - n)
i = 1
Pth = Dir(Defpath & "*.", vbDirectory)
Do While Pth <> ""
If Pth <> "." And Pth <> ".." Then
ReDim Preserve Folders(i)
Folders(i) = Defpath & Pth
i = i + 1
End If
DoEvents
Pth = Dir()
Loop
'--------------
''Dim files() 'パラメータ側に移したので、使わない
Dim p As Variant
Dim j As Long
Dim fn As String
Const EXT As String = "xlsx" '拡張子 ★
For Each p In Folders
fn = Dir(p & "\" & "*." & EXT, vbNormal)
Do While fn <> ""
If Pth <> "." And Pth <> ".." Then
ReDim Preserve Files(j)
Files(j) = p & "\" & fn
j = j + 1
End If
DoEvents
fn = Dir()
Loop
Next
End Sub
'(配列変数 Files に格納されます)
'//
2.
'Open Close を繰り返す部分は、以下にすれば一回で済みます。
Private CommandButton3_Click()
Dim SrcBk As Workbook
Dim DestBK As Workbook
Dim i As Long, j As Long
Dim strFilename '文字型は使えません。
Dim HyokaPATH As String
Dim fpath2 As String
HyokaPATH = Application.DefaultFilePath '★
If HyokaPATH Like "*\" Then Mid(HyokaPATH,1, Len(HyokaPATH) -1)
fpath2 = HyokaPATH & "\" & MyBook '★
Dim Files() '取得 Call MakingFileList 用の変数
Call MakingFileList(Files)
Set DestBK = Workbooks.Open(fpath2)
'行を加算
i = 1
For Each strFilename In Files
On Error Resume Next
Set SrcBk = Workbooks.Open(strFilename, False, True) 'ReadOnlyにしました。
With SrcBk
.ActiveSheet.Range("J2").Copy DestBK.ActiveSheet.Cells(i, 1)
.ActiveSheet.Range("D2").Copy DestBK.ActiveSheet.Cells(i, 2)
.ActiveSheet.Range("K1").Copy DestBK.ActiveSheet.Cells(i, 3)
.ActiveSheet.Range("M1").Copy DestBK.ActiveSheet.Cells(i, 4)
.ActiveSheet.Range("O1").Copy DestBK.ActiveSheet.Cells(i, 5)
.ActiveSheet.Range("L1").Copy DestBK.ActiveSheet.Cells(i, 6)
.ActiveSheet.Range("L6").Copy DestBK.ActiveSheet.Cells(i, 7)
.ActiveSheet.Range("L7").Copy DestBK.ActiveSheet.Cells(i, 8)
.ActiveSheet.Range("L8").Copy DestBK.ActiveSheet.Cells(i, 9)
.ActiveSheet.Range("L9").Copy DestBK.ActiveSheet.Cells(i, 10)
.Close False
i = i + 1
End With
If Error <> 0 Then
Debug.Print strFilename 'エラーつまり、プロテクトが掛かっている場合など
End If
On Error GoTo 0
Next
End Sub
'//
No.1
- 回答日時:
こんにちは
ヒントのみですが・・・
(実際に実行して、動作確認はしてはいませんので、悪しからず)
1)
原状は、Dir関数でエクセルファイルのみを指定しているので、サブフォルダなどは無視されていることになります。
例えば、指定フォルダ内のファイル/フォルダを順に処理して、サブフォルダが見つかったら「そのフォルダ内を検索」するような仕組みにしておけばよいですよね。
そのまま記述すると、「サブフォルダ内にサブフォルダが見つかったら~~」と入れ子の記述を続けなければならなくなりますので、これを回避するために。「サブフォルダが見つかったら、フォルダを引数にして自分自身を呼び出す(再帰)」ような仕組みにしておくのが効率が良いでしょう。
<参考>
https://www.moug.net/tech/exvba/0060088.html
2)
原因がはっきりとしないので、何が適切なのか測りかねますが、二種類の方法を考えてみました。
①openイベントで実行されるマクロが原因の場合、イベントの発生を停止しておけばよさそう
Application.EnableEvents = False
とすることでイベントを無効にできますので、openイベントが発生しなくなります。
(最後に元に戻しておくのを忘れずに)
<参考>
https://docs.microsoft.com/ja-jp/office/vba/api/ …
②ブックオープン時にマクロを無効化する
エクセルのセキュリティレベルでマクロを無効化したのと同じ状態にしてから、ブックを開きます。
<参考>
https://docs.microsoft.com/ja-jp/office/vba/api/ …
開いたブック内のマクロのせいではなく、2重に開く等のエラーが発生するのであれば、ファイルを開く前に「既に開いているかのチェックを行う」か、「On Errorステートメントでエラー処理を行う」ようにしておくか等で回避できるものと思います。
ご質問内容には直接関係はありませんが、ご提示の「CommandButton3_Click」でセル値の転記の際に、一つ転記するごとに転記元、転記先のファイルを開く/閉じるを繰り返していますが、あまりにも効率が悪すぎます。(ファイルの開閉には時間が掛かりますので)
・転記元、転記先のファイルを開く
・必要なセル値(複数)を順に全て転記
・転記元、転記先のファイルを閉じる
だけで済むはずです。
実際には、転記先のファイルは次の転記元ファイルの処理の際にも開くことになるのでしょうから、処理全体に渡って開いておいて、処理終了時に(一度だけ)閉じれば済むものと思われます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) vbaのエラー対応(実行時エラー7:メモリが不足しています) 4 2023/04/24 00:20
- Visual Basic(VBA) VBAのユーザーフォームのテキストボックスに入力制限をしたい 6 2022/11/15 08:28
- Visual Basic(VBA) エクセルVBA(実行時エラー438)の対処法を教えてもらえないでしょうか 3 2023/04/22 13:43
- Visual Basic(VBA) 【VBA】印刷マクロのループ処理が反映されません 3 2022/08/09 02:15
- Visual Basic(VBA) 3個のfileのセルデータを1個のfileのセルに貼り付けるVBAコードですが。 1 2023/02/20 09:21
- Excel(エクセル) マクロでテキストファイルを読み込んだ際の最終セルにデータと改行が含まれる問題の改善方法 2 2022/03/25 16:50
- Visual Basic(VBA) フォルダの場所を可変にしたいです(マクロ) 4 2023/05/11 10:00
- Visual Basic(VBA) 【前回の続き続きです、ご教示ください】VBAの記述方法がわかりません。 2 2022/08/24 20:49
- Excel(エクセル) VBA フォルダ見える化のコードについて 2 2023/06/19 15:04
- Visual Basic(VBA) ExcelVBAに関する質問 3 2023/02/17 10:47
関連するカテゴリからQ&Aを探す
今、見られている記事はコレ!
-
弁護士が語る「合法と違法を分けるオンラインカジノのシンプルな線引き」
「お金を賭けたら違法です」ーーこう答えたのは富士見坂法律事務所の井上義之弁護士。オンラインカジノが違法となるかどうかの基準は、このように非常にシンプルである。しかし2025年にはいって、違法賭博事件が相次...
-
釣りと密漁の違いは?知らなかったでは済まされない?事前にできることは?
知らなかったでは済まされないのが法律の世界であるが、全てを知ってから何かをするには少々手間がかかるし、最悪始めることすらできずに終わってしまうこともあり得る。教えてgooでも「釣りと密漁の境目はどこです...
-
カスハラとクレームの違いは?カスハラの法的責任は?企業がとるべき対応は?
東京都が、客からの迷惑行為などを称した「カスタマーハラスメント」、いわゆる「カスハラ」の防止を目的とした条例を、全国で初めて成立させた。条例に罰則はなく、2025年4月1日から施行される。 この動きは自治体...
-
なぜ批判コメントをするの?その心理と向き合い方をカウンセラーにきいた!
今や生活に必要不可欠となったインターネット。手軽に情報を得られるだけでなく、ネットを介したコミュニケーションも一般的となった。それと同時に顕在化しているのが、他者に対する辛らつな意見だ。ネットニュース...
-
大麻の使用罪がなかった理由や法改正での変更点、他国との違いを弁護士が解説
ドイツで2024年4月に大麻が合法化され、その2ヶ月後にサッカーEURO2024が行われた。その際、ドイツ警察は大会運営における治安維持の一つの方針として「アルコールを飲んでいるグループと、大麻を吸っているグループ...
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
【マクロ】変数に入れるコード...
-
EXCEL VBA 指定したファイルが...
-
【マクロ】名前を保存する際に...
-
【Excel VBA】ファイル名が一...
-
【マクロ】EXCELで読込したCSV...
-
VBAでワークブックの名前を変数...
-
エクセルマクロで不特定なファ...
-
データ参照先が別ファイルの場...
-
エクセルファイルを開く時、関...
-
秀丸:あらかじめ設定した複数...
-
フォルダ内のexcelファイルを順...
-
VBA EXCELファイル選択⇒指定セ...
-
エクセル(マクロ)のファイル...
-
ファイルを開かずにマクロを実行
-
【VBA】フォルダ内のファイル全...
-
Excel:上書き保存時にワークシ...
-
Excelマクロで指定したファイル...
-
Excelのマクロでファイルを開く...
-
エクセルファイルをHTML化する...
-
Accessのaccdbファイルを起動で...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
【マクロ】EXCELで読込したCSV...
-
EXCEL VBA 指定したファイルが...
-
【マクロ】名前を保存する際に...
-
フォルダ内のexcelファイルを順...
-
エクセルマクロで不特定なファ...
-
【Excel VBA】ファイル名が一...
-
ファイルを開かずにマクロを実行
-
フォルダ内のブック全部にパス...
-
EXCELマクロを無効にして開く方法
-
エクセル 複数ファイルの一括...
-
エクセル(マクロ)のファイル...
-
accessフォルダを移動したらフ...
-
秀丸:あらかじめ設定した複数...
-
データ参照先が別ファイルの場...
-
エクセルファイルを開く時、関...
-
Excelファイルがマクロを含むか...
-
ファイルの保存場所を変えたら...
-
エクセルのシートの数を数えた...
-
VBAでワークブックの名前を変数...
-
Excelのマクロでファイルを開く...
おすすめ情報
プログラムのコメントが少なくて伝わりにくいですが
CommandButton1_Click()の部分がフォルダを参照させる部分
CommandButton2_Click()の部分が出力ファイル選択
CommandButton3_Click()の部分がファイル名取得しセルの内容をコピーして指定された別ブックへ転記するプログラムです