質問するログイン新規登録
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Office 365

Office 365は、マイクロソフトが販売している企業向けクラウドベースのグループウエアサービス。電子メールや予定表、Webサイト構築、オンラインストレージ、ビデオ会議などビジネスで必要な機能を備えています。クラウドサービスのため、自社での専用サーバーの設置の必要がないことが特徴です。

Q&A

解決済

1回答

502閲覧

VBA:更新日比較によるファイル読み込み実行有無の実装

juska

総合スコア16

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Office 365

Office 365は、マイクロソフトが販売している企業向けクラウドベースのグループウエアサービス。電子メールや予定表、Webサイト構築、オンラインストレージ、ビデオ会議などビジネスで必要な機能を備えています。クラウドサービスのため、自社での専用サーバーの設置の必要がないことが特徴です。

0グッド

0クリップ

投稿2023/08/14 03:43

0

0

実現したいこと

特定のフォルダに格納されているExcelファイルの特定のセルを読み込んで、別ファイルの一覧表Excelに転記。
格納されているファイルのフォーマットはすべて同じ前提。

初回読み込み後、ファイルの更新日が新しくなっているものは再読み込みを行い、転記済の情報を上書きする。
更新日が同じもの(新しくなっていないもの)は読み込まない。

前提

VBAで以下コードを実装済

VB

1Sub AppendDataToExistingFile() 2 Dim TargetFilePath As String 3 Dim TargetWorkbook As Workbook 4 Dim TargetSheet As Worksheet 5 Dim SourceFolder As String 6 Dim SourceFile As String 7 Dim SourceFileUpdateDate As Date 8 Dim NextRow As Long 9 10 ' 抽出元のフォルダパス 11 SourceFolder = "C:\Users\aaaaaaaaaaaaaaa\OneDrive\デスクトップ\test\" 12 13 ' 既存のExcelファイルパス 14 TargetFilePath = "C:\Users\aaaaaaaaaaaaaaa\OneDrive\デスクトップ\test.xlsm" 15 16 ' 既存のExcelファイル 17 Set TargetWorkbook = Workbooks.Open(TargetFilePath) 18 19 ' 追記するシートを選択(1番目のシート) 20 Set TargetSheet = TargetWorkbook.Sheets(1) 21 22 ' 最終行を特定す 23 NextRow = TargetSheet.Cells(TargetSheet.Rows.Count, 1).End(xlUp).Row + 1 24 25 ' 抽出元のフォルダ内のExcelファイルを走査 26 SourceFile = Dir(SourceFolder & "*.xlsx") 27 28 Do While SourceFile <> "" 29 ' 抽出元ファイルの更新日を取得す 30 SourceFileUpdateDate = FileDateTime(SourceFolder & SourceFile) 31 32 ' 更新日の比較 33 If SourceFileUpdateDate > TargetSheet.Cells(NextRow, 7).Value Then 34 ' 更新日が新しい場合のみデータを読み込む 35 Call ImportDataFromSourceFile(SourceFolder & SourceFile, TargetSheet, NextRow) 36 NextRow = NextRow + 1 37 End If 38 39 ' 次のファイルを取得 40 SourceFile = Dir 41 Loop 42 43 ' 既存のExcelファイルを保存 44 TargetWorkbook.Save 45 46 ' 既存のExcelファイルを閉る 47 TargetWorkbook.Close SaveChanges:=False 48 49 ' 完了メッセージを表示 50 MsgBox "データの追記が完了しました。", vbInformation 51End Sub 52 53Sub ImportDataFromSourceFile(SourceFilePath As String, TargetSheet As Worksheet, NextRow As Long) 54 Dim SourceWorkbook As Workbook 55 Dim SourceSheet As Worksheet 56 Dim SourceValue1 As Variant 57 Dim SourceValue2 As Variant 58 Dim SourceText1 As String 59 Dim SourceText2 As String 60 Dim SourceText3 As String 61 Dim SourceRange As Range 62 Dim SourceText4 As String 63 Dim PasteRangeValue As Range 64 65 ' 抽出元のExcelファイルを開く 66 Set SourceWorkbook = Workbooks.Open(SourceFilePath) 67 Set SourceSheet = SourceWorkbook.Sheets(3) ' 抽出元のシートを指定(3番目) 68 69 ' セル1の抽出 70 SourceValue1 = SourceSheet.Range("W2:Z2").Value 71 ' セル2の抽出 72 SourceValue2 = SourceSheet.Range("W3:Z3").Value 73 ' セル3の抽出 74 SourceText1 = SourceSheet.Range("W43").Value 75 ' セル4の抽出 76 SourceText2 = SourceSheet.Range("B8").Value 77 ' セル5の抽出 78 SourceText3 = SourceSheet.Range("B15").Value 79 ' セル6の抽出 80 Set SourceRange = SourceSheet.Range("U40:Z40") 81 ' 更新日の抽出 82 SourceText4 = Format(FileDateTime(SourceFilePath), "yyyy/mm/dd hh:mm:ss") 83 84 ' データの書き込み 85 TargetSheet.Cells(NextRow, 1).Value = SourceFilePath 86 ' セル1の転記 87 TargetSheet.Cells(NextRow, 2).Value = SourceValue1 88 ' セル2の転記 89 TargetSheet.Cells(NextRow, 3).Value = SourceValue2 90 ' セル3の転記 91 TargetSheet.Cells(NextRow, 4).Value = SourceText1 92 ' セル4の転記 93 TargetSheet.Cells(NextRow, 5).Value = SourceText2 94 ' セル5の転記 95 TargetSheet.Cells(NextRow, 6).Value = SourceText3 96 ' 更新日の転記 97 TargetSheet.Cells(NextRow, 7).Value = SourceText4 98 99 ' セル6の転記 100 Set PasteRangeValue = TargetSheet.Cells(NextRow, 8) 101 PasteRangeValue.Resize(1, SourceRange.Columns.Count).Value = SourceRange.Value 102 103 ' 抽出元のファイルを閉じます 104 SourceWorkbook.Close SaveChanges:=False 105End Sub 106

発生している問題・エラーメッセージ

更新日の新旧にかかわらずすべてのファイルを何度も読み込んでしまいます。

該当のソースコード

上記の通り

試したこと

更新日の比較方法等をいくつか試しましたがNGでした。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

下記のようにしてはどうでしょうか。

vba

1Sub AppendDataToExistingFile() 2.. 3...... 4.. 5 6 7 Do While SourceFile <> "" 8 ' 抽出元ファイルの更新日を取得する。 9 SourceFileUpdateDate = FileDateTime(SourceFolder & SourceFile) 10 ' ファイル名を調べて、すでに記録済みのファイルかどうかを調べる。 11 Dim FoundCell As Range 12 Set FoundCell = TargetSheet.Columns(1).Find(What:=SourceFolder & SourceFile, LookIn:=xlValues, LookAt:=xlWhole) 13 14 ' 記録済みのファイルである場合: 15 If Not FoundCell Is Nothing Then 16 ' 記録されている更新日と、現在の更新日を比較 17 If SourceFileUpdateDate > FoundCell.Offset(0, 6).Value Then 18 ' 更新日が新しい場合のみデータを読み込む 19 Call ImportDataFromSourceFile(SourceFolder & SourceFile, TargetSheet, FoundCell.Row) 20 End If 21 Else 22 ' 新しいファイルなのでデータを追加する。 23 Call ImportDataFromSourceFile(SourceFolder & SourceFile, TargetSheet, NextRow) 24 NextRow = NextRow + 1 25 End If 26 27 ' 次のファイルを取得 28 SourceFile = Dir 29 Loop 30 31...以下略... 32 33End Sub

上のコードでは、まず抽出元からファイルを1つずつ読み込んだときに
そのファイルが既存のExcelの記録中に存在するか判定しています。

存在する場合は、更新日を比較して、更新日が新しければ、データを読み込み、記録行を更新します。
存在しない場合は、もともとのコードの通り、データを最下行(の1つ下)に追加するだけです。

投稿2023/08/14 04:38

編集2023/08/14 04:42
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

juska

2023/08/14 06:57

ありがとうございました! 下記コードに修正したところ希望通り実装できました。 ----------- Sub AppendDataToExistingFile() Dim TargetFilePath As String Dim TargetWorkbook As Workbook Dim TargetSheet As Worksheet Dim SourceFolder As String Dim SourceFile As String Dim SourceFileUpdateDate As Date Dim NextRow As Long ' 抽出元のフォルダパス SourceFolder = "C:\Users\aaaaaaaaaaaaaaaaa\OneDrive\デスクトップ\test\" ' 既存のExcelファイルパス TargetFilePath = "C:\Users\aaaaaaaaaaaaaaaaa\OneDrive\デスクトップ\test.xlsm" ' 既存のExcelファイル Set TargetWorkbook = Workbooks.Open(TargetFilePath) ' 追記するシートを選択(1番目のシート) Set TargetSheet = TargetWorkbook.Sheets(1) ' 最終行を特定す NextRow = TargetSheet.Cells(TargetSheet.Rows.Count, 1).End(xlUp).Row + 1 ' 抽出元のフォルダ内のExcelファイルを走査 SourceFile = Dir(SourceFolder & "*.xlsx") ' 初回書き込み位置を4行目に設定 NextRow = 4 Do While SourceFile <> "" ' 抽出元ファイルの更新日を取得する。 SourceFileUpdateDate = FileDateTime(SourceFolder & SourceFile) ' ファイル名を調べて、すでに記録済みのファイルかどうかを調べる。 Dim FoundCell As Range Set FoundCell = TargetSheet.Columns(1).Find(What:=SourceFolder & SourceFile, LookIn:=xlValues, LookAt:=xlWhole) ' 記録済みのファイルである場合: If Not FoundCell Is Nothing Then ' 記録されている更新日と、現在の更新日を比較   ※更新日のセルに修正 If SourceFileUpdateDate > FoundCell.Offset(0, 2).Value Then ' 更新日が新しい場合のみデータを読み込む Call ImportDataFromSourceFile(SourceFolder & SourceFile, TargetSheet, FoundCell.Row) End If Else ' 新しいファイルなのでデータを追加する。 Call ImportDataFromSourceFile(SourceFolder & SourceFile, TargetSheet, NextRow) NextRow = NextRow + 1 End If ' 次のファイルを取得 SourceFile = Dir Loop ' 既存のExcelファイルを保存 TargetWorkbook.Save ' 既存のExcelファイルを閉る TargetWorkbook.Close SaveChanges:=False ' 完了メッセージを表示 MsgBox "データの追記が完了しました。", vbInformation End Sub Sub ImportDataFromSourceFile(SourceFilePath As String, TargetSheet As Worksheet, NextRow As Long) Dim SourceWorkbook As Workbook Dim SourceSheet As Worksheet Dim SourceValue1 As Variant Dim SourceValue2 As Variant Dim SourceText1 As String Dim SourceText2 As String Dim SourceText3 As String Dim SourceRange As Range Dim SourceText4 As String Dim PasteRangeValue As Range ' 抽出元のExcelファイルを開く Set SourceWorkbook = Workbooks.Open(SourceFilePath) Set SourceSheet = SourceWorkbook.Sheets(3) ' 抽出元のシートを指定(3番目) ' セル1の抽出 SourceValue1 = SourceSheet.Range("W2:Z2").Value ' セル2の抽出 SourceValue2 = SourceSheet.Range("W3:Z3").Value ' セル3の抽出 SourceText1 = SourceSheet.Range("W43").Value ' セル4の抽出 SourceText2 = SourceSheet.Range("B8").Value ' セル5の抽出 SourceText3 = SourceSheet.Range("B15").Value ' セル6の抽出 Set SourceRange = SourceSheet.Range("U40:Z40") ' 更新日の抽出 SourceText4 = Format(FileDateTime(SourceFilePath), "yyyy/mm/dd hh:mm:ss") ' データの書き込み TargetSheet.Cells(NextRow, 1).Value = SourceFilePath ' セル1の転記 TargetSheet.Cells(NextRow, 3).Value = SourceValue1 ' セル2の転記 TargetSheet.Cells(NextRow, 4).Value = SourceValue2 ' セル3の転記 TargetSheet.Cells(NextRow, 5).Value = SourceText1 ' セル4の転記 TargetSheet.Cells(NextRow, 6).Value = SourceText2 ' セル5の転記 TargetSheet.Cells(NextRow, 7).Value = SourceText3 ' 更新日の転記 TargetSheet.Cells(NextRow, 2).Value = SourceText4 ' セル6の転記 Set PasteRangeValue = TargetSheet.Cells(NextRow, 8) PasteRangeValue.Resize(1, SourceRange.Columns.Count).Value = SourceRange.Value ' 抽出元のファイルを閉じます SourceWorkbook.Close SaveChanges:=False End Sub
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.30%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問