[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『複数の別ブックからデータを転記するマクロを作りたい』(kaori)
フォルダ内にある複数ブックにあるデータ(様式はどれも同じ)を最終行までコピーし、一つのシートに集約するマクロを作ってみたのですが、ブックを開くところまで動くのに転記が最後のデータだけになってしまい困っています
どこを修正すべきか教えていただけると嬉しいです
よろしくお願いします
Sub 一括取得()
Dim folder As String
Dim file As String
Dim shtName As String
Dim nowRow As Long
Dim shtTaisyo As Worksheet
Dim shtSyuyaku As Worksheet
Dim startRow As Long
Dim lastRow As Long
Dim ext As String
Dim wb As Workbook
Dim fso As Object
Dim f As Object
With Application.FileDialog(msoFileDialogFolderPicker)
If .Show = True Then
folder = .SelectedItems(1)
End If
End With
file = Dir(folder & “\*.xlsx”)
shtName = “入力用”
startRow = 4
nowRow = 2
Set shtSyuyaku = Thisworkbook.Sheets(shtName)
Set fso = CreateObject(“Scripting.FileSystemObject”)
For Each f In fso.GetFolder(folder).Files
ext = LCase(fso.getextensionName(f.Name))
Set wb = Workbooks.Open(folder & “\” & f.Name)
Set shtTaisyo = wb.Sheets(shtName)
lastRow = shtTaisyo.Cells(startRow, 1), shtTaisyo.Cells(lastRow, 15)).Copy (shtSyuyaku.Cells(nowRow, 1))
nowRow = nowRow + lastRow - (startRow - 1)
wb.Close
Set wb = Nothing
Next
MsgBox “完了”
End Sub
< 使用 Excel:Excel2016、使用 OS:Windows10 >
こんにちは ^^ コピーは-1を返していると思われます、結果 nowRowが変化していないのではないでしょうか。 nowRow 止めて、lastRowだけでいけば、すっきりするのでは。 最初のlastRowは2で別途lastRowを取得する。とかで行けるか もしれません。。。← 多分 ^^;。。。。m(__)m (隠居じーさん) 2021/02/15(月) 11:07
shtName = “入力用”
startRow = 4
nowRow = 2
Set shtSyuyaku = Thisworkbook.Sheets(shtName)
Set fso = CreateObject(“Scripting.FileSystemObject”)
For Each f In fso.GetFolder(folder).Files
ext = LCase(fso.getextensionName(f.Name))
Set wb = Workbooks.Open(folder & “\” & f.Name)
Set shtTaisyo = wb.Sheets(shtName)
lastRow = shtTaisyo.Cells(shtTaisyo.Rows.Count, 1).End(xlUp).Row
shtTaisyo.Range(shtTaisyo.Cells(startRow, 1), shtTaisyo.Cells(lastRow, 15)).Copy (shtSyuyaku.Cells(nowRow, 1))
nowRow = nowRow + lastRow - (startRow - 1)
wb.Close
Set wb = Nothing
Next
MsgBox “完了”
End Sub
(kaori) 2021/02/15(月) 12:34
あの〜確かに、不必要なコードがあったり、後始末の 問題とかはあるかも。。。ですがこちらは賛否両論なので 私の勘違いも、あったかもですが動いていますですよ。。。 (#^^#)v (隠居じーさん) 2021/02/15(月) 13:11
え。。。そぉなのですね。。。 あの、読込先のシート名は 全て 入力用 ですよね。 書込み先のシーと名も 入力用 で、合っていますでしょうか。 読込み開始行は、全て、4行目から、最終行まで、みたいですけど その範囲に、何も情報が無い。。。とかは。。。ないですよね。 とりあえず、今、頭に、パッと浮かんだのはこれくらいでして また、何か解りましたら、現れますが。。。 他の回答者様のアドバイスをお待ちくださいませ。。。m(_ _)m (隠居じーさん) 2021/02/15(月) 15:01
こんばんは ^^ これではどうなりますでしょう。。。( ̄▽ ̄) メッセージが出るか、又は、ダメでしたら、教えて下さいね。 Option Explicit Sub 一括取得02() Dim folder As String Dim shtName As String Dim nowRow As Long Dim shtTaisyo As Worksheet Dim shtSyuyaku As Worksheet Dim startRow As Long Dim lastRow As Long Dim wb As Workbook Dim fso As Object Dim f As Object Dim fdg Set fdg = Application.FileDialog(msoFileDialogFolderPicker) If fdg.Show = False Then Set fdg = Nothing Exit Sub End If folder = fdg.SelectedItems(1) shtName = "入力用" startRow = 4 nowRow = 2 Set shtSyuyaku = ThisWorkbook.Sheets(shtName) Set fso = CreateObject("Scripting.FileSystemObject") For Each f In fso.GetFolder(folder).Files Set wb = Workbooks.Open(folder & "\" & f.Name) Set shtTaisyo = wb.Sheets(shtName) With shtTaisyo lastRow = .Cells(.Rows.Count, 1).End(xlUp).Row If lastRow < 5 Then MsgBox "要情報確認" & Chr(13) & wb.Name .Range(.Cells(startRow, 1), .Cells(lastRow, 15)).Copy shtSyuyaku.Cells(nowRow, 1) End With With shtSyuyaku nowRow = .Cells(.Rows.Count, 1).End(xlUp).Row + 1 End With wb.Close Set shtTaisyo = Nothing Set wb = Nothing Next Set fdg = Nothing Set shtSyuyaku = Nothing Set fso = Nothing MsgBox "完了" End Sub (隠居じーさん) 2021/02/15(月) 15:50
■1
こだわりがなければ、インデントを付けた方がコードが見やすく(メンテナンスしやすく)なるとおもいますので、整理してみてはどうでしょうか。
■2
提示のコードだと、フォルダを選択してもらえなかった時でも次に進んでしまいますので「folder」が空っぽだったら、処理を中断するようにしたほうがよいとおもいます。
■3
一度しか使わないようなものもわざわざ変数に格納しています。
ダメとはいいませんが、複雑化して分かりづらくなる原因にもなるので、コード中にそのまま記述できないか検討したほうがよいとおもいます。
■4
↓はどのような意図で記述したのでしょうか?変数に格納するだけで使ってないですよ。
ext = LCase(fso.getextensionName(f.Name))
参考にされたコードが何かわかりませんが、本来はExcelブックかどうか拡張子で判定していたのではありませんか?
※ピンと来ない場合は↓を読んでみてください。
http://officetanaka.net/excel/vba/filesystemobject/sample07.htm
■5
↓も参考にされたコードがわかりませんが、どちらか要らないですよ。(たぶん)
file = Dir(folder & "\*.xlsx")
For Each f In fso.GetFolder(folder).Files
ただ、前者を採用とするのであれば、ループ処理の部分が不足してますし、後者を採用とするなら「■4」のとおり、拡張子判定の部分が抜けてます。
■6
ちなみに、ネット検索で見つかったコードや、質問掲示板のコードを、ただ実行してみたり眺めていたりするだけだと、なかなか理解しづらいとおもいますので、【ステップ実行】という手法を使い1行ずつ実行していき、どのような動きをするのか確認したり、変数に何が格納されているのかチェックするようにすると、理解しやすいとおもいます。
ついては【ステップ実行】という言葉を聞いたことがなければ↓をよんでみてください。
【ステップ実行】 https://www.239-programing.com/excel-vba/basic/basic023.html http://plus1excel.web.fc2.com/learning/l301/t405.html
ついでに↓も覚えてしまいましょう。
【イミディエイトウィンドウ】 https://www.239-programing.com/excel-vba/basic/basic024.html https://excel-ubara.com/excelvba1/EXCELVBA486.html
【ローカルウィンドウ】 https://excel-ubara.com/excelvba4/EXCEL266.html http://excelvba.pc-users.net/fol8/8_2.html
■7
以上を踏まえて整理するとこんな感じになります。(コンパイルエラーにならないことのみチェック済)
※※ 修正のためいったん削除 ※※
(もこな2) 2021/02/15(月) 19:18
Sub 一括取得_整理1() '// FileSystemObjectを使ってみる Dim folder As String Dim nowRow As Long, lastRow As Long Dim fso As Object Dim f As Object Dim shtSyuyaku As Worksheet
Stop 'ブレークポイントの代わり
'▼ダイアログを出して、ユーザーに処理するフォルダを選択してもらう With Application.FileDialog(msoFileDialogFolderPicker) If .Show = True Then folder = .SelectedItems(1) Else MsgBox "フォルダが選択されなかったので処理を中止します" Exit Sub End If End With
'▼諸準備 Set shtSyuyaku = ThisWorkbook.Sheets("入力用") Set fso = CreateObject("Scripting.FileSystemObject") nowRow = 2
'▼指定されたフォルダにあるファイルを巡回して、Excelブックだったら開いて処理する Set shtSyuyaku = ThisWorkbook.Sheets("入力用") Set fso = CreateObject("Scripting.FileSystemObject") nowRow = 2 For Each f In fso.GetFolder(folder).Files If LCase(fso.GetExtensionName(f.Name)) Like "xls*" Then With Workbooks.Open(f.Path).Sheets("入力用") lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
If lastRow >= 4 Then With .Range("A4", .Cells(lastRow, 15)) .Copy shtSyuyaku.Cells(nowRow, 1) 'コピペを実行 nowRow = nowRow + .Rows.Count 'コピペした行数を加算 End With End If
.Parent.Close End With End If Next f MsgBox "完了" End Sub '----------------------------------------------------------- Sub 一括取得_整理2() '// Dir関数を使ってみる Dim folder As String, lastRow As Long, ファイル名 As String Dim 出力セル As Range: Set 出力セル = ThisWorkbook.Sheets("入力用").Range("A2")
Stop 'ブレークポイントの代わり
'▼ダイアログを出して、ユーザーに処理するフォルダを選択してもらう With Application.FileDialog(msoFileDialogFolderPicker) If .Show = True Then folder = .SelectedItems(1) Else MsgBox "フォルダが選択されなかったので処理を中止します" Exit Sub End If End With
'▼指定されたフォルダにあるファイルを巡回して、Excelブックだったら開いて処理する ファイル名 = Dir(folder & "\*.xls?") Do Until ファイル名 = "" With Workbooks.Open(folder & "\" & ファイル名).Sheets("入力用") lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row If lastRow >= 4 Then With .Range("A4", .Cells(lastRow, 15)) .Copy 出力セル 'コピペを実行 Set 出力セル = 出力セル.Offset(.Rows.Count) 'コピペした行数を加算 End With End If
.Parent.Close End With
ファイル名 = Dir() Loop
MsgBox "完了" End Sub
(もこな2) 2021/02/17(水) 21:35
また、同じく無理にとは言いませんが現状のコードを示してみてはどうでしょうか。
何点か冗長とおもえる部分の指摘をしましたし、正解は1つではありませんから、他の回答者さんから別アプローチでのアドバイスがあるかもしれません。
(もこな2) 2021/02/26(金) 17:42
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.