Access VBA Split利用方法

このQ&Aのポイント
  • VBAを使ってAccessでtxtファイルをインポートし、配列を利用してカンマ区切りにしたい場合、Split関数を使用することができます。
  • Split関数を使用して配列を条件分岐に利用し、テーブルに書き込むことも可能です。
  • VBAでの基本的な使い方から、条件分岐での利用方法まで、詳しく解説しています。
回答を見る
  • ベストアンサー

Access VBA Split利用方法

お世話になります。 VBAを勉強している最中です。 Accessを利用して、txtファイルをインポート後、テーブルの項目を配列利用して カンマ区切りにしたいのと、Splitを利用して、配列を条件分岐に利用して、テーブルに 書き込みをしたいとおもってます。 おそらく基本的なことで自分で勉強するべきと思うのですが 漠然なイメージしかない状態で、ヒントやこういう方法があるなど 教えていただけますでしょうか 基本的な使い方ですと Private Sub XXX_Click() str = Split("あああ いいい ううう")   MsgBox str(1) End Sub 上記の用な利用方法と思いますが、このような使い方ではなく test(0)のような使い方をして、条件分岐で利用したいと おもってます。 イメージとしては、下記のようなことをイメージしてます。 Public Sub Test()   Dim test() As String Dim row As String   Dim iNum1 As Long,   Dim iNum2 As Long      DoCmd.SetWarnings False   DoCmd.RunSQL "DELETE * FROM data"  DoCmd.TransferText acImportFixed, "インポート定義", "data", "d:\data.txt"   DoCmd.SetWarnings True   iNum1 = 0   iNum2 = 0   Do While xxx      If test(0) = 0 Then          iNum1 = iNum1 + 1 iNum2 = 1      Else         xxxx      End If   Loop End Sub ここでSplitを利用してどのように指定するのが望ましいのか考えてしまってます。 test = row.Split(" ") を利用する場合、どのように連結(row)させるのかが不明です。 知識不足もあり、説明がわかりづらいと思うのですが、よろしくお願いします。

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

  • ベストアンサー
  • piroin654
  • ベストアンサー率75% (692/917)
回答No.5

No4について少し説明をしておきます。 No4のSub cmdFile2() について、   Do While Not EOF(1)     Line Input #1, LineofText     '配列にデータを格納     arrayText = Split(LineofText, ",")     '配列の要素をテーブルに格納       rs.AddNew       For i = 0 To UBound(arrayText)       rs.Fields(i) = arrayText(i)       Next i       rs.Update   Loop arrayTextの型はVariantですが、配列を格納する場合は この型で行ないます。 (1) Line Input #1, LineofText はテキストファイルのデータを一行ずつ変数LineofTextに読み込む コードで、たとえば、LineofTextに 関東,東京,群馬,神奈川,千葉 のようにデータが格納されている考えてください。 (2) 次に、 arrayText = Split(LineofText, ",") によって、カンマを区切りとして配列を arrayTextに作ります。 (3) ここからが肝要ですが、補足に >Dim aaa() As String のような状態にした場合、 >そこからどうテーブルの列をを認識させて、 >aaa(0)がフィールド1の配列として認識させる >ことができるのかがよくわかっていないといいますか・・・ >わかりづらいでしょうか とありますが、     '配列の要素をテーブルに格納       rs.AddNew       For i = 0 To UBound(arrayText)       rs.Fields(i) = arrayText(i)       Next i       rs.Update は、ちょうどこの部分を表しているところで、 rs.Fields(i) = arrayText(i) の、左側はテーブルのi番目のフィールドを表し、右側は 配列のi番目の要素を表しています。今、テーブルと テキストファイルの列の数は同じとしているので、 rs.Fields(i) = arrayText(i) のようにして、テーブルの列の位置と、配列の要素の位置 を簡単に同期させることができます。 (4) 一つの行の処理が終わったら、 Do While Not EOF(1) Loop によって、次の行に進み、データを同様に取得します。 なお、テーブルの次の行に新しくデータを格納するのは、 rs.AddNew rs<Update のくみあわせによって、新しい行にレコードを追加する ことができることになります。そして新たにiは0から 始まるので行の先頭からレコードを追加できる、と いうことになります。 なお、テキストファイルにNullがある場合、たとえば、 関東,東京,,神奈川,千葉 関西,大阪,兵庫,,奈良 中国,広島,岡山,鳥取,山口 のように、ところどころデータが空の部分がある場合、 No4のSub cmdFile2()を実行すると、長さが0の文字列 を格納できません、といったエラーが出ます。 そういった場合は、まさに条件分岐で、たとえば、   Do While Not EOF(1)     Line Input #1, LineofText     '配列にデータを格納     arrayText = Split(LineofText, ",")     '配列の要素をテーブルに格納       rs.AddNew       For i = 0 To UBound(arrayText)       If arrayText(i) <> "" Then       rs.Fields(i) = arrayText(i)       Else       rs.Fields(i) = "空"       End If       Next i       rs.Update   Loop のようにして、処理を行ないます。 なお、Accessのテーブルのフィールドの型は テキスト型としています。 以上です。

almajiro1111
質問者

お礼

piroin654 様 お礼がおくれてしまいすいませんでした。 記載頂いた内容すごい分かりやすく説明頂き感謝です。 ご説明頂いた内容でチャレンジしてみます。 いそがしい所ありがとうございました。 また、質問させていただくこともあるかもしれませんが よろしくお願いいたします。

その他の回答 (4)

  • piroin654
  • ベストアンサー率75% (692/917)
回答No.4

一応、テーブル定義を利用した方法はわかっていると いう前提で以下に。 ファイルへのアクセスを行なう方法は以下にあります。 http://support.microsoft.com/kb/151262/ja これを利用して回答してみます。 (1) たとえば、以下のようなカンマ切りのテキストファイルが あるとします。フィールド数でいえば5あります。 関東,東京,群馬,神奈川,千葉 関西,大阪,兵庫,京都,奈良 中国,広島,岡山,鳥取,山口 このテキストファイルをmdbファイルと同じフォルダに おきます。 アクセスのテーブルにF1,F2,F3,F4,F5の名前でフィールドを 設定し、テーブルを設定し、名前をテーブル1とします。 (2) 以下に二つのプロシージャを提示します。この中身が 何をしているかを理解できないとなかなか難しい ものがありますが。 なお、以下でDAOを使用しているので、コード表の ツール→参照設定からDAOにチェックを入れてください。 Microsoft DAO xx Object Library xxは3.6のような数値です。 Sub cmdFile1()   Dim LineofText As String   Dim arrayText As Variant   Dim strPath As String   Dim i As Long   'テキストファイルを開く   Open CurrentProject.Path & "\test1.txt" For Input As #1   '一行ずつ変数に読み込む   Do While Not EOF(1)     Line Input #1, LineofText     '配列にデータを格納     arrayText = Split(LineofText, ",")     '配列の要素を一つずつ表示     For i = 0 To UBound(arrayText)       MsgBox arrayText(i)     Next   Loop   Close #1 End Sub Sub cmdFile2()   Dim LineofText As String   Dim arrayText As Variant   Dim strPath As String   Dim i As Long   Dim db As DAO.Database   Dim rs As DAO.Recordset   Set db = CurrentDb   Set rs = db.OpenRecordset("テーブル1", dbOpenDynaset)   'テキストファイルを開く   Open CurrentProject.Path & "\test1.txt" For Input As #1   '一行ずつ変数に読み込む   Do While Not EOF(1)     Line Input #1, LineofText     '配列にデータを格納     arrayText = Split(LineofText, ",")     '配列の要素をテーブルに格納       rs.AddNew       For i = 0 To UBound(arrayText)       rs.Fields(i) = arrayText(i)       Next i       rs.Update   Loop   Close #1   rs.Close: Set rs = Nothing   db.Close: setdb = Nothing End Sub 以上ですが、テキストファイルの列数とテーブルの列数は 同じであること前提にしているのでそれほど難しい ことではないのですが。 配列にデータを読み込んでそれをメッセージで個別に表示したり、 テーブルに格納したりということをしています。 普通はこのようなことはしませんが、質問に答えて ということで。 何かあれば補足してください。

  • nicotinism
  • ベストアンサー率70% (1019/1452)
回答No.3

その 「txtファイル」の内容を数行でかまいません、提示できませんか? 中味は適当にぼかしても構いませんが、 文字数やデータ型が変わってしまうものは止めてくださいね。 > DoCmd.TransferText acImportFixed, "インポート定義", "data", "d:\data.txt" で acImportFixed を指定していますが固定長ファイルなのでしょうか? またインポートウィザードで進めていった場合はテーブルに期待したとおりに データが収まっていますか? ↓では入っているようですが? >テーブルtestに、3列(フィールド1・フィールド2・フィールド3)あるとして、 >この3項目を配列を利用した際のSplitメソッドの利用・指定の方法がよくわかりませんでした。 この目的は? どこまで出来ていて何処から判らないのかが、私には分かりません。。。 最初に書いたようにオリジナルデータの例示 最終的に求めたい結果の例示 が必要かと。。

almajiro1111
質問者

お礼

nicotinism 様 >最初に書いたようにオリジナルデータの例示 >最終的に求めたい結果の例示 >が必要かと。。 確かにその通りですね。 一度 自分でもう一度内容を考えて見ます。 不明点がでましたら改めて質問させていただくかも しれませんが、よろしくお願いいたします。 忙しい所ありがとうございました。

  • piroin654
  • ベストアンサー率75% (692/917)
回答No.2

失礼しました。No1の(1)のCSVファイルはtxtファイルに訂正です。

  • piroin654
  • ベストアンサー率75% (692/917)
回答No.1

質問文を何回か読み直しましたが、どうにも 意図が汲み取れない・・・というか想像を たくましくすると勘違いが起こりそうなので、 >Accessを利用して、txtファイルをインポート後、テーブルの項目 >を配列利用してカンマ区切りにしたいのと、Splitを利用して、 >配列を条件分岐に利用して、テーブルに書き込みをしたいと >おもってます。 について、 (1) このようなCSVファイルがある。 (2) テーブルのフィールドにこのように書き込みたい。 といったことを具体的にしたほうが回答がしやすいのですが。

almajiro1111
質問者

補足

piroin654 様 お世話になります。 わかりにくいというか理解しがたい質問ですいません。 まだ素人に毛が生えた状態な為 ご了承ください。m(__)m (1)やりたいことは、単純にボタンを押したらtxtファイルをインポートを行う (2)インポート後、一つのテーブルの、Nullになっている項目に数字や文字列をいれたい この二つになります。 条件分岐の記述については勉強がてら、とりあえず自力でやりたいとおもってまして 詳しくは記載してません。(わがままですいません。) もしかしたら改めて質問させていただくかもしれません。 ご指導いただきたい内容として、 テーブル testに、3列(フィールド1・フィールド2・フィールド3)あるとして、この3項目を配列を利用した際のSplitメソッドの利用・指定の方法がよくわかりませんでした。 Dim strVal Dim aryStrings strVal = "山田,佐藤,中山,山本,鈴木" aryStrings = Split(strVal, ",") 上記のような状態だとイメージしやすいんですが、変数として、 Dim aaa() As String のような状態にした場合、そこからどうテーブルの列をを認識させて、 aaa(0)がフィールド1の配列として認識させることができるのかがよくわかっていないといいますか・・・ わかりづらいでしょうか 不明点だらけでしたら本当すいませんです。 以上 よろしくお願いいたします。

関連するQ&A

  • アクセスのクエリでSplit関数は使えないのですか

    レコードにaaa/bbb/cccと入っていて、 クエリで SELECT Split([テーブル1]![フィールド1],"/") AS test FROM テーブル1; とすると、 式に未定義関数 <関数名> があります。(Error 3085) になります。 VBAでやるとしたら Sub test() Dim str As String str = "aaa/bbb/ccc" Debug.Print Split(str, "/")(1) End Sub のような事がしたいのですが クエリでは無理なのでしょうか?

  • access一部のフィールドを他のテーブルへVBA

    先日 https://okwave.jp/qa/q10245651.html において > table2の新しいデータとして > table1のデータをコピーしたい、 単に追加で ということであれば、という 御回答: Sub Test() Dim StrSQL As String StrSQL = "INSERT INTO table2 SELECT table1.* FROM table1;" DoCmd.SetWarnings False DoCmd.RunSQL StrSQL DoCmd.SetWarnings True End Sub ---------------------- 上記の 回答をいただき うまく稼働しました 部分的にフィールドを別テーブルに 移動するとき ここでは table1のフィールド名 IDに table2のフィールド名 bに 入っている数値 にい 1を加えた数値を 移動したいのですが Public Function Test() Dim tb1 As Table Dim tb2 As Table tb1 = table1 tb2 = table2 Dim strSQL As String strSQL = "INSERT INTO table2![ID]SELECT"("[b]"FROM tablel)+1" (table1のフィールド[b]の数値に1を加えた数値を table2のフィールド[ID]に移行する、というつもりです) DoCmd.SetWarnings False DoCmd.RunSQL strSQL DoCmd.SetWarnings True End Function 稼働しません すみません 宜しくお願い致します (ついでながら ここで でてくるb というのは テーブル table3 の IDの総和 すなわち SELECT Count(table3.ID) AS b FROM table3; 要は table3の最後のレコードの次のレコードの 番号の数値を table2のIDに移動したい というわけであります) (いずれのIDや bについても 数値型 長整数型 重複あり です)

  • Access2000 VBA - 変更の履歴が取れません

    下記コードで、If Nz(Ctr.OldValue, "") <> Nz(Ctr.Value, "") Thenの行で「指定した式には値がありません」というエラーが出てしまいます。 他のQ&Aで見つけた成功例のほぼコピペなのですが・・・・ どこが悪いのか、ご教示頂けないでしょうか? よろしくお願い致します。 __________________________________________________________________________________________ Private Sub Form_BeforeUpdate(Cancel As Integer) Dim Ctr As Control Dim strSQL As String For Each Ctr In Me.Controls If Nz(Ctr.OldValue, "") <> Nz(Ctr.Value, "") Then strSQL = "insert into 履歴 values('currentuser'," & Ctr.Value & _ ",'" & Ctr.Name & "','" & Ctr.OldValue & "',#" & Now() & "#)" DoCmd.SetWarnings False DoCmd.RunSQL strSQL DoCmd.SetWarnings True End If Next Ctr End Sub

  • アクセスVBAです

    Sub test() Dim DB As Database Dim T As TableDef Dim myTable As String myTable = "Table1" Set DB = OpenDatabase(CurrentProject.FullName) For Each T In DB.TableDefs If T.Name = myTable Then DoCmd.DeleteObject acTable, myTable Exit For End If Next DB.Close Set DB = Nothing End Sub これを実行しようとすると Dim DB As Database の部分で コンパイルエラー プロジェクトではなく、ユーザ定義型を指定してください。 と言うエラーになります。 Dim DB As Objectにすればエラーにならずに進みますが 何が原因なのでしょうか?

  • アクセスで定数を利用したい。

    アクセスで定数を利用したい。 アクセス初心者です。 フォームで取得した値を他のプロシージやクエリでも利用したいと思っています。 標準モジュールで Public Sub 学年() Dim nen As Integer nen = Forms![F_start]![対象学年] end sub というのをつくってみましたがうまくいきません。"nen"というのを活用したいと思っています。 dim の代わりにpublic constを使ってみたりもしましたが,うまくできません。 また,nenを他のプロシージャで利用しようと思って,次のようなものもつくりましたが,うごきません。 Private Sub 学級編成1_Click() Dim nen As Integer Select Case nen Case nen = 1 DoCmd.OpenQuery "Q_学級編成1" Case nen = 2 DoCmd.OpenQuery "Q_学級編成2" Case nen = 3 DoCmd.OpenQuery "Q_学級編成3" End Select End Sub あとクエリの抽出条件にもつかいたいのですが・・・ ご指導よろしくお願いいたします。

  • アクセスVBA 追加クエリ

    下記クエリが一つあります。 [Q_商品] ID 商品名 価格 色 サイズ 重さ 送料 備考 [Q_商品]から、[T_テスト]をテーブルの作成から作りました。 [T_テスト]は、毎回利用する時に、すべてデリートして、[Q_商品]のデータを追加したいです。 [T_テスト]のデータの、すべてデリートは下記VBAでできました。 Private Sub コマンド40_Click() 'システムメッセージの非表示 DoCmd.SetWarnings False DoCmd.RunSQL "DELETE FROM T_テスト" 'システムメッセージの表示 DoCmd.SetWarnings True End Sub [Q_商品]のデータを追加するVBAを教えて下さい。 よろしくお願い致します。

  • VBAでバイナリエディタを作ろうとしています

    テキストファイルを内部でバイナリとして開いて 16進数のダンプファイルとして新たなテキストに保存することはできたのですが 逆がどうしてもできません。 やり方としては、 03 E3 BD 71 80… のようなテキストデータをバイナリにして16進数にして保存したテキストファイルをダイアログから呼び出してもう一度元のテキスト文章に戻すという作業です。 とりあえず、まずは以下のコードでエクセル内で16進数を元の文章データに変換しようとしています。 Sub binaryToText() Dim fname As String Dim str() As Byte Dim row As Integer row = 1 fname = "Test.txt" '16進数ファイル Open fname For Binary As #1 Do Until EOF(1) ReDim Preserve str(row) Get #1, , str(row) row = row + 1 Loop Close #1 End Sub hex関数やchr関数を使う必要があるのでしょうか? VBAは始めたばかりで根本的なところで間違っているかもしれませんがよろしくお願いします。

  • EXCELファイルからACCESSへインポート

    質問させていただきます。 ACCESSのフォームから、EXCELファイルを選択してEXCELの内容を、 テーブルにインポートさせたいのですが。以下の方法で行って いるのですが、テーブルに反映されません。 Private Sub cmd_Import_Click() Dim InitialFileName As String Dim varTitle As Variant Dim FileName As String InitialFileName = "hoge.xls" varTitle = "ファイルを開く" FileName = GETHOGEOPEN(varTitle, InitialFileName) DoCmd.SetWarnings False DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, "T_HOGE", FileName, True DoCmd.SetWarnings True MsgBox "完了しました" End Sub ACCESS → ACCESS2003 SP3 EXCEL →EXCEL2003 SP3 よく見ると、すでにEXCELのバージョン指定が違う(汗) これが原因かも・・・・(汗) わかる方がいらっしゃったら教えてください。

  • vbaの繰り返し処理について

    vbaです。 Sub Test1() Dim Str As String Dim Pnt1 As Long Dim Pnt2 As Long Str = Range("A1") Pnt1 = InStr(Str, "重 http://") If Pnt1 <= 0 Then Exit Sub Pnt2 = InStr(Pnt1, Str, "要") If Pnt2 <= 0 Then Range("B1") = Mid(Str, Pnt1 + 2) Else Range("B1") = Mid(Str, Pnt1 + 2, Pnt2 - (Pnt1 + 2)) End If End Sub という式でA1からA2.A3と下にURLが入っており空欄になるまで同じ処理をしたいのですがどのように変更すれば作動しますでしょうか?

  • access2000で使用者を履歴に残したい。

    履歴を取るのに「更新者=使用者」これは、currentuserですよね! 「テーブル全体を履歴に残す」バージョンでテーブルの更新者の規定値にcurrentuser()と入れればできる!と思ったのですが、テーブルではその式は利用できませんでした。モジュールに何か書き込まないとできないのでしょうか? 現在のモジュールは以下の通りです。 Sub History_a() Dim Ctr As Control Dim strSQL As String For Each Ctr In Me.Controls If Ctr.ControlType = 109 Then If Ctr.OldValue <> Ctr.Value Then strSQL = "insert into あ履歴 select * FROM あ " & _ "where 顧客コード = " & Me.顧客コード DoCmd.SetWarnings False DoCmd.RunSQL strSQL DoCmd.SetWarnings True Exit Sub End If End If Next Ctr End Sub ここで作成した使用者を顧客コードをキーに最終更新日の更新者を取り出すという、ややこしくてわけがわからなくなりそうなことも可能でしょうか?

専門家に質問してみよう