EXCELのVBAでのCSVファイル読込みと検索

このQ&Aのポイント
  • エクセルのマクロでCSVファイルを読み込み、電話番号とFAX番号を検索する作業を行う方法について説明します。
  • 作成したVBAコードで一部問題が発生し、プログラムが実行されない場合、どのように修正すればよいかについてアドバイスを受け取りたいです。
  • 操作環境やCSVファイルの内容に問題がないことを確認し、エラーの原因を特定する方法について教えてください。
回答を見る
  • ベストアンサー

EXCELのVBAでのCSVファイル読込みと検索

エクセルのマクロでCSVファイルを読み込み、その行の得意先サブコードをキー項目として別のCSVファイルを検索し電話番号とFAX番号を取得するという作業を下記のようなコードで作成しました。 Dim Obj As Object Dim Path As String Dim FName As String Dim i As Long Dim buf As String Dim tmp As Variant Dim WSH As Variant Dim CN As ADODB.Connection Dim RS As ADODB.Recordset '自分のPCのデスクトップをPathとして設定します。 Set WSH = CreateObject("Wscript.Shell") Path = WSH.SpecialFolders("Desktop") & "\" '得意先マスタ.csvをOPENする際の準備処理 '3行目のPropertiesがCSVファイルの定義(excelをOPENする時とは異なります) Set CN = New ADODB.Connection CN.Provider = "Microsoft.Jet.OLEDB.4.0" CN.Properties("Extended Properties") = "Text;HDR=YES;FMT=Delimited" CN.Open Path '得意先サブマスタ.CSVを開きます。 Open Path & "得意先サブマスタ.csv" For Input As #1 i = 1 Do Until EOF(1) Line Input #1, buf tmp = Split(buf, ",") If i = 1 Then Else Cells(j, 1).Value = Left(tmp(3), 4) '会社コード Cells(j, 2).Value = Right(tmp(3), 4) '店舗コード Cells(j, 3).Value = tmp(3) '会社@店舗 Cells(j, 4).Value = tmp(4) '得意先コード Cells(j, 5).Value = tmp(5) '店舗名 Set RS = New ADODB.Recordset RS.Open "SELECT * FROM 得意先マスタ.csv WHERE 得意先コード = " & tmp(4) & " ", CN If RS.EOF Then Cells(j, 6).Value = "???" Cells(j, 7).Value = "???" Else Cells(j, 6) = RS.Fields("電話番号") Cells(j, 7) = RS.Fields("FAX番号") End If End If i = i + 1 Loop このコードで動作確認すると途中で動作が止まってしまい応答なし状態になってしまいます。どこで止まるかは一定ではありません。CSVファイルの内容も確認したのですが、特におかしいような箇所はありませんでした。 OSはWINDOWS7、EXCELは2016です。 コード自体に修正した方がいいような箇所があればアドバイスいただきたいと思っております。宜しくお願い致します。

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

  • ベストアンサー
  • ushi2015
  • ベストアンサー率51% (241/468)
回答No.1

こんにちは どうせADOを使うのなら、 Sub test1()   Dim CN As ADODB.Connection   Dim RS As ADODB.Recordset   Dim 最終行 As Long   Dim sSql As String   Dim i   As Long      Set CN = New ADODB.Connection      With CN     .Provider = "Microsoft.Jet.OLEDB.4.0"     .Properties("Extended Properties") = "Text;HDR=Yes;FMT=Delimited;"     .Open CreateObject("Wscript.Shell").SpecialFolders("Desktop") & "\"   End With      Set RS = New ADODB.Recordset      sSql = ""   sSql = sSql & "SELECT "   sSql = sSql & "LEFT(a.会社@店舗, 4) AS 会社コード, "   sSql = sSql & "RIGHT(a.会社@店舗, 4) AS 店舗コード, "   sSql = sSql & "a.会社@店舗, "   sSql = sSql & "a.得意先コード, "   sSql = sSql & "a.店舗名, "   sSql = sSql & "b.電話番号, "   sSql = sSql & "b.FAX番号 "   sSql = sSql & "FROM 得意先サブマスタ.csv AS a "   sSql = sSql & "LEFT JOIN "   sSql = sSql & "   得意先マスタ.csv AS b "   sSql = sSql & "ON a.得意先コード = b.得意先コード "      RS.Open sSql, CN     For i = 1 To RS.Fields.Count     Cells(1, i) = RS.Fields(i - 1).Name   Next     Range("A2").CopyFromRecordset RS       RS.Close End Sub のようにしてはどうですか?

takazou
質問者

お礼

構文として大変参考になりました。どうもありがとうございました。

その他の回答 (1)

  • Prome_Lin
  • ベストアンサー率42% (201/470)
回答No.2

私は、むずかしいことは分かりませんので、もっと、単純化してしまいます。 例えば、「Worksheets(1)」が電話番号などを読み込ませたいシートだとして、あと2つシートを追加しておきます。 そして、「Worksheets(2)」に「得意先マスタ.csv」を読み込ませます。 もちろん、「Worksheets(3)」には「得意先サブマスタ.csv」を読み込みます。 VBAの例としては、 Sub Test() Open "D:\Programming\得意先マスタ.csv" For Input As #1 l = 0 Do Until EOF(1) Line Input #1, a b = Split(a, ",") l = l + 1 For i = 0 To UBound(b) Worksheets(2).Cells(l, i + 1).Value = b(i) Next i Loop Close #1 End Sub という具合に、「Microsoft」云々のようなややこしい(私にとっては)ものは使いません。 「Worksheets(1)」と「(2)」に「csv」ファイルが読み込めれば、あとは「Find」によって検索をかけて、見つければいいと思います。 もしくは、別のエクセルを起動して、シートを2つ用意し、そのエクセルに「csv」ファイルを読み込ませておいて、「Find」で検索をかける、とすれば、元のエクセルに不要なデータを取り込む必要はありません。 冒頭言いましたように、私には、「ADODB」などの扱いは、難しすぎるので、単純にしたいです。

takazou
質問者

お礼

おっしゃられている事、よくわかります。 FIND でも VLOOKUP でも実行可能ですよね。 ただ今回はADOの勉強をしたかったので、こういう質問をさせていただきました。 どうもありがとうございました。

関連するQ&A

  • Excel VBA ADOでのCSV取込みについて

    下記は、Excel VBAでADOを使って、CSVデータを取り出すソースです。ソースは、とあるサイトからほぼ丸写しです。 Sub main()   Const DRIVER As String = "DRIVER={Microsoft Text Driver (*.txt; *.csv)};DBQ="   Const PROVIDER As String = "Provider=MSDASQL;Extended Properties="""   Dim cn As New ADODB.Connection   Dim rs As New ADODB.Recordset   Dim idx As Integer   Dim strSQL As String   cn.ConnectionString = PROVIDER & DRIVER & "C:\"""   cn.Open   '全件数取得   strSQL = "SELECT * FROM Sample.csv"   'CSVファイルの内容を取得   Set rs = cn.Execute(strSQL)   rs.MoveFirst   Do Until rs.EOF     For idx = 0 To rs.Fields.Count - 1       Debug.Print rs.Fields(idx).Value '←ここ     Next idx     rs.MoveNext   Loop   Set rs = Nothing   cn.Close   Set cn = Nothing End Sub ここで、「'←ここ」と示した行のrs.Fields(idx).Valueって、実際には「001」と書かれた値は、ダブルクォーテーションでも入ってない限りは「1」と変換されちゃいますよね?これをちゃんと、実際の値「001」のまま取得することって出来ないのでしょうか?

  • アクセスVBA。ADO

    CSVから列を分割してテーブルにしたいかったので 下記のコードを記述しましたが、 Dim cn As ADODB.Connection Dim rs As New ADODB.Recordset Dim datacount As Long Set cn = New ADODB.Connection With cn .ConnectionString = "Provider=Microsoft.jet.OLEDB.4.0;Data Source=" & CurrentProject.Path & "\;" .Properties("Extended Properties").Value = "text;HDR=YES;" .Open End With Set rs = cn.Execute("SELECT * FROM 構成マスタ.csv") datacount = rs.Fields.Count For i = 0 To datacount strsql = "SELECT " & rs.Fields(i).Name & " INTO " & rs.Fields(i).Name & " FROM 構成マスタ.csv;" cn.Execute strsql Next i rs.Close cn.Close Set rs = Nothing Set cn = Nothing SQLを実行するところで、「日付エラー」となってしまいます。 データには特に日付等はないのでエラーになる原因がわかりません。 どなたかご教示いただけますでしょうか。

  • excel vba で .mdb のデータ抽出

    excel vba で postdata.mdbのpostレコードから条件に合うデータを抽出しようとしています。 数日間、いろいろ調べていますが分かりません。 おそらく、SQLの部分だと思うのですが・・・ adoは初めて使う素人なので教えていただけないでしょうか。 On Error GoTo ErrGyo Set cn = New ADODB.Connection cn.Provider = "Microsoft.Jet.OLEDB.4.0" cn.Open ThisWorkbook.Path & "\postdata.mdb" Dim Rs As ADODB.Recordset Dim SQL As String Dim T_ken As String Dim T_si As String Dim T_mati As String Dim i As Long T_ken = TextBox1.Value  ’フォームにテキストボックス T_si = TextBox2.Value T_mati = TextBox3.Value SQL = "SELECT * FROM post WHERE ken like '" & T_ken & "' and si LIKE '" & T_si & "' and mati LIKE '" & T_mati & "'" Set Rs = New ADODB.Recordset Rs.Open SQL, cn, adOpenForwardOnly, adLockReadOnly MsgBox Rs.RecordCount  ’ここでチェックすると -1 となる??? If Rs.RecordCount = 0 Then MsgBox "該当するレコードは見つかりませんでした。", vbInformation Else For i = 1 To Rs.RecordCount Cells(i, 1) = Rs!num Cells(i, 2) = Rs!ken Cells(i, 3) = Rs!si Cells(i, 4) = Rs!mati Rs.MoveNext Next End If Rs.Close: Set Rs = Nothing cn.Close: Set cn = Nothing Exit Sub ErrGyo: MsgBox "postdataへの接続に失敗しました", vbCritical

  • 【VBA】ExcelマクロでCSVファイルに保存したデータが""で囲まれてしまう

    添付図のような、Excel2003で作成した表内のデータを CSVで保存するマクロを作成したのですが、 図のように、CSVファイルに「""」で値が囲まれた状態で、 保存されてしまいます。 下記にマクロを記載しますので、 どうすれば文字列が「""」で囲まれずに、 カンマ区切りだけのデータで出力されるのか、 ご存知の方おられましたら、ご教示お願い致します。 Sub csv保存() Dim フォルダ名 As String Dim パス名 As String Dim ファイル名 As String Dim データ As Variant Dim 行数 As Long, 列数 As Integer Dim i As Integer, j As Long, k As Long ファイル名 = "test.csv" フォルダ名 = "csv" パス名 = ActiveWorkbook.Path & "\" & _ フォルダ名 'csvフォルダが存在しなければ作成する If Dir(パス名, vbDirectory) = "" Then MkDir パス名 End If ChDir パス名 Open ファイル名 For Output As #1 For i = 1 To Worksheets.Count Worksheets(i).Activate Worksheets(i).Cells(1, 1).Select ActiveCell.CurrentRegion.Select 行数 = Selection.Rows.Count 列数 = Selection.Columns.Count For j = 1 To 行数 For k = 1 To 列数 - 1 データ = Selection.Cells(j, k) _ .Value Write #1, データ; Next k Write #1, Selection.Cells(j, 列数) _ .Value Next j Next i Close #1 End Sub

  • Excel実行時エラー[80004005]について

    ExcelのVBAにてSQLのSELECT文を実行し、取得したデータを一覧表示する仕組みを作っています。 同じプログラムを使用者する者7名の内、1名のみ以下のエラーが発生しています。 どのように対応すればよいか、ご教示ください。 環境 Excel2010 状況 SELECTの実行時 「実行時エラー[80004005] [Microsoft][ODBC Driver Manager] データ ソース名および指定された既定のドライバーが見つかりません。」 実行ソース Private Sub exeSelect(sheetNm as string ,sqlSt as String) Dim i As Integer Dim j As Integer Dim cn As ADODB.Connection Dim rs As ADODB.Recordset Dim bookNm As String bookNm = ThisWorkbook.FullName Set cn = New ADODB.Connection cn.Provider = "MSDASQL" cn.ConnectionString = "Driver={Microsoft Excel Driver (*.xls)};" & "DBQ=" & bookNm & "; ReadOnly=False;" cn.Open←ここでエラー Set rs = New ADODB.Recordset rs.Open sqlSt, cn, adOpenStatic j = START_ROW Do Until rs.EOF For i = 0 To rs.Fields.Count - 1 Worksheets(sheetNm).Cells(j, i + 1).Value = rs(i).Value Next j = j + 1 rs.MoveNext Loop rs.Close cn.Close End Sub

  • excelでのado接続での検索

    シートのA列に商品コードが入っており、別ブックのA列に商品コード、B列に商品名が入っています。 現シートのA列を一行ずつ読んで、その商品コードをキーに別ブックの商品コードを検索し一致するコードがあれば現シートのB列に別ブックの商品名をセットする、という作業を勉強がてらado接続を使って実行したいと思い、下記のコードで実行してみました。 Dim CN As ADODB.Connection Dim RS As ADODB.Recordset Set CN = New ADODB.Connection CN.Provider = "Microsoft.Jet.OLEDB.4.0" CN.Properties("Extended Properties") = "Excel 8.0" CN.Open "C:\Users\*****\Desktop\shohinmaster.xls" For i = 2 To 最終行 Set RS = New ADODB.Recordset RS.Open "SELECT * FROM [shohin$] WHERE 商品コード = '" & Cells(i, 1) & "' ", CN If RS.EOF Then Cells(i, 2) = "???" Else Cells(i, 2) = 商品名 End If Next これで実行しますと、現シートの商品名は空白という結果になります。???とすらセットされませんでした。 また RS.Open の行の '" & Cells(i, 1) & "' という箇所なのですが、現シートの商品コードは数値で 入っているのですが、別シートの商品コードは文字列としてセットされていますのでこの形式にしております。 EXCELは2016、OSはWINDOWS7です。 どこが誤っているのかアドバイスいただければ幸いです。宜しくお願い致します。

  • VBAのデバックをどなたかお手伝いください。

    もちろん自分でも調べてはいるのですが、急いでいるため、もしどなたか教えてくだされば大変助かります。 この(下記の)Then 以降からがわかりません。 Do Until rs.EOF '該当レコードあり If rs!MCD = "3162" Then '--------------------------------------------- strcriteria = "CAT = '" & rs!CAT & "'" ' --- A rs2.Find strcriteria, 0, adSearchForward If rs2.EOF Then ' Else rs!仕入単価世代1 = rs!仕入単価 rs!仕入単価 = rs2!discount End If '--------------------------------------------- rs!更新日 = Now() rs.Update End If 情報が不足していればお答えします。どうぞ宜しくお願いいたします。 (補足)これより前に入力されているのは以下のものです。 Dim cn As ADODB.Connection Dim cn2 As ADODB.Connection Dim rs As ADODB.Recordset Dim rs2 As ADODB.Recordset Dim strmsg As String Dim lngRet As Long Dim strcriteria As String Set cn = CurrentProject.Connection Set rs = New ADODB.Recordset Set cn2 = CurrentProject.Connection Set rs2 = New ADODB.Recordset rs.Open "商品2_T", cn, adOpenKeyset, adLockOptimistic rs2.Open "商品2_T25discountてすと", cn2, adOpenKeyset, adLockOptimistic

  • 【VBA】アタッチとデタッチについての認識

    VBAを勉強中の者です。カテ違いならすいません。 ******************************************************* Sub test1() Dim cn As ADODB.Connection Dim rs As ADODB.Recordset Set cn = New ADODB.Connection Set rs = New ADODB.Recordset cn.Open "Provider=SQLOLEDB;Data Source=localhost\SQLEXPRESS; " & _ "Initial Catalog=" & データベース名 & ";" & _ "Integrated Security=SSPI" rs.Open "テーブル1", cn, adOpenStatic, adLockOptimistic MsgBox rs.RecordCount rs.Close: Set rs = Nothing cn.Close: Set cn = Nothing End Sub ******************************************************* このコードで アタッチは「Set cn = New ADODB.Connection」、 デタッチは「cn.Close: Set cn = Nothing」 になりますか? ご教授よろしくお願い致します。

  • Accessでのデータベースの使用(VBA)

    Private Sub 実行_Click() Dim cn As ADODB.Connection Dim rs As ADODB.Recordset Dim StSQL As String Set cn = CurrentProject.Connection Set rs = New ADODB.Recordset strSQL = "INSERT INTO マスタ(コード) VALUES(コード) ;" rs.Open strSQL, cn, , adLockOptimistic '//前のコード(エラーになりました。) ' rs.Close 'cn.Close 'Set rs = Nothing 'Set cn = Nothing Set rs = Nothing: Close Set cn = Nothing: Close Accessを使用したvbaのコードの書き方について教えてほしいです。毎度Access の質問ばかりしてすみません。以下のコードはADOを使用してマスタというテーブルを読み込んで最後にrs.CloseでRecordSetを開放しようとしたのですが「オブジェクトが閉じている場合は、操作は許可されません。」というエラーメッセージが出てしまい原因がわかりませんでした。Openしていて開いているはずなのにエラーが出てしまい、 Set rs = Nothing: Closeに変えたら治りました。何故rs.Closeではエラーが出てしまったのでしょうか。 もう一つお聞きしたいです。 strSQL = "INSERT INTO マスタ(コード) VALUES(コード) ;"でコードという名前を付けたテキストボックスの値をマスタテーブルのコードの列に追加したいのですがテキストボックスの値の取り方が分かりません。(コード.Value)とやってみてもだめでした。どうやったらSQL文でテキストボックスの値をテーブルに追加できるんでしょうか。

  • アクセス VBAのエラー

    以下のコードをwindowsXPで問題なく使っていましたが、windows7で使ったところ 「保存できません」というエラーメッセージが出ます。ただ全く同じコードを(だと思うのですが)リストボックスのダブルクリックで実行すると作動します。参考に二つのコードを書いておきます。 何か原因に心当たりのある方よろしくお願いします。 (コマンドボタン) Private Sub コマンド選択_Click() Dim namecode As String namecode = リスト会員 Dim cn As New ADODB.Connection Dim rs As New ADODB.Recordset Set cn = CurrentProject.Connection rs.Open "MT_会員", cn, adOpenKeyset, adLockOptimistic rs.Find "会員IDkai = " & namecode rs!Selectedkai = True '-1 rs.Save Me!リスト会員.Requery リスト印刷会員.Requery rs.Close: Set rs = Nothing cn.Close: Set cn = Nothing End Sub (ダブルクリック) Private Sub リスト会員_DblClick(Cancel As Integer) Dim namecode As String namecode = リスト会員 Dim cn As New ADODB.Connection Dim rs As New ADODB.Recordset Set cn = CurrentProject.Connection rs.Open "MT_会員", cn, adOpenKeyset, adLockOptimistic rs.Find "会員IDkai = " & namecode rs!Selectedkai = True '-1 rs.Save Me!リスト会員.Requery リスト印刷会員.Requery rs.Close: Set rs = Nothing cn.Close: Set cn = Nothing End Sub

専門家に質問してみよう