いちばん失敗した人決定戦

以下のような2つのCSVファイルがあるとします。

【hoge1.csv】
aaa,bbb,ccc,ddd
1,2,3,4

【hoge2.csv】
aaa,bbb,ddd,eee,fff
1,2,4,5,6


Accessをあまり使用したことがないので教えていただきたいのですが、
hoge1.csv、hoge2.csvを、以下のような形で
Accessの1つのテーブルにインポートする事はできるのでしょうか?

----------------------------
| aaa | bbb | ccc | ddd | eee | fff |
| 1 | 2 | 3 | 4 |  |  |
| 1 | 2 |  | 4 | 5 | 6 |
----------------------------
※「aaa」「bbb」…をフィールド名としたいです


vb等でプログラムを自作するしかないのでしょうか?
何か良い方法がありましたら教えてください。お願いします。

A 回答 (4件)

NO3です。

成功しましたのでお知らせします。

1 横長のCSVデータをエクセルに取り込みます。二つのシートになります。
CSVデータはテキストファイルとしてワードなどに保存しておきます。エクセルでそのファイルを開きますが、テキストファイルを開くこととし、区切り文字はカンマと指定します。
シート1にSOGE1のデータを、シート2にSOGE2を取り込みます。

2 エクセルの横長のデータを縦長のデータに変換します。
データの変換にはシート関数があるようですが、使い方が私はわかりませんので下に示した二つのマクロを使ってしーと3しーと4に縦長のデータに変換しました。

3 アクセスにテーブルとして取り込みます。シート3とシート4をsheet3,sheet4という名前で二つのテーブルとして取り込みました。これに縦長のフィールドひとつだけのテーブルをつくり、aaaからfffまでのデータを入れておきます。テーブル3という名前になっています。

4 アクセスでテーブル3とsheet3の間にaaaなどのフィールド1によってリレーションを作り、結合の種類をテーブル3のすべてとsheet3のけっごうとします。クエリーでテーブル3とsheet3を選択して得られたデータをクエリー9という名前で保存します。
5.クエリー9とsheet4の間にリレーションを作ります。結合の種類はクエリー9のすべてとsheet4の結合とします。クエリー9とsheet4を呼び込んでクエリーを作ります。実行すればここでご希望のデータが得られます。

Sub Macro1()
'
' Macro1 Macro
' マクロ記録日 : 2014/3/25 ユーザー名 :
'
Dim i As Integer, j As Integer
For i = 1 To 2
For j = 1 To 5
Worksheets(3).Cells(j, i) = Worksheets(1).Cells(i, j)
Next
Next
'
End Sub

Sub Macro2()
'
' Macro2 Macro
' マクロ記録日 : 2014/3/25 ユーザー名 :
'
Dim i As Integer, j As Integer
For i = 1 To 2
For j = 1 To 5
Worksheets(4).Cells(j, i) = Worksheets(2).Cells(i, j)
Next
Next
'


'
End Sub
テーブル3.フィールド1Sheet3.フィールド1クエリー9.フィールド2Sheet4.フィールド1Sheet4.フィールド2
aa1a1
bb2b2
cc3
dd4d4
ee5
ff6
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
実際に試すところまでやっていただき、本当にありがたいです。
しかし、今すぐ実際に確認できる状況でなくなってしまったので、後ほど試してみます。
取り急ぎお礼まで…。

お礼日時:2014/03/26 12:28

すでに回答されていますが、全然別のやり方を提案いたします。

4つの段階があります。
1 横長のCSVデータをエクセルに取り込みます。二つのシートになります。
2 エクセルの横長のデータを縦長のデータに変換します。
3 アクセスにテーブルとして取り込みます。二つのテーブル。これに縦長のフィールドひとつだけのテーブルをつくり、aaaからfffまでのデータを入れておきます。
4 アクセスで3つのテーブルにリレーションを作ってから、選択クエリーで3つのテーブルをひとつにします。そうするとご希望のテーブルができるはずです。
これから試しにやってみます。
    • good
    • 0

他にも流用できそうなものを作ってみました。



CSV ファイルが「hoge1.csv」「hoge2.csv」だけであれば、
以下の2行を変更することで動くと思います。

  Const CPATH = "D:\HogeHoge\tmp\" ' CSV ファイルまでのパス
  Const CTBL = "テーブル名" ' 作成テーブル名

その他に処理する CSV ファイルがあるのなら、

  For Each vDp In Array("hoge1.csv", "hoge2.csv")

部分を変更すれば動くと思います。
また、
毎回テーブルを作り直していますが、処理に合わせて変更してください。

なお、細かいエラー処理は入れてません。


標準モジュールに記述後、実行するのは以下

Public Sub test()
  Dim dic As Object, dicW As Object
  Dim oFso As Object
  Dim sBuf As String
  Dim vDp As Variant, vDc As Variant, v As Variant
  Dim vAry As Variant
  Dim i As Long, j As Long
  Dim sSql As String
  Const CPATH = "D:\HogeHoge\tmp\" ' CSV ファイルまでのパス
  Const CTBL = "テーブル名" ' 作成テーブル名
  Const CSQL = "INSERT INTO {%1}({%2}) " _
    & "SELECT {%2} FROM [{%3}] IN '{%4}'[text;FMT=Delimited;HDR=YES;IMEX=1];"

  ' 各 CSV の項目部分の入手
  Set dic = CreateObject("Scripting.Dictionary")
  Set oFso = CreateObject("Scripting.FileSystemObject")
  For Each vDp In Array("hoge1.csv", "hoge2.csv")
    With oFso.OpenTextFile(CPATH & vDp)
      sBuf = .ReadLine
      dic.Add vDp, CreateObject("Scripting.Dictionary")
      For Each vDc In Split(Replace(sBuf, """", ""), ",")
        dic(vDp)(Trim(vDc)) = Null
      Next
      .Close
    End With
  Next
  Set oFso = Nothing

  ' 項目の重複排除と昇順並び替え
  Set dicW = CreateObject("Scripting.Dictionary")
  For Each vDp In dic.Keys
    For Each vDc In dic(vDp).Keys
      dicW(vDc) = Null
    Next
  Next
  vAry = dicW.Keys
  Set dicW = Nothing
  For i = 0 To UBound(vAry) - 1
    For j = i + 1 To UBound(vAry)
      If (vAry(i) > vAry(j)) Then
        v = vAry(i)
        vAry(i) = vAry(j)
        vAry(j) = v
      End If
    Next
  Next

  ' テーブルの作り直し:オートナンバ「an」を付加し、各項目を長整数で作成
  sSql = "DROP TABLE " & CTBL & ";"
  On Error Resume Next
  CurrentDb.Execute sSql
  On Error GoTo 0
  sSql = "CREATE TABLE " & CTBL & "( an AUTOINCREMENT"
  For Each v In vAry
    sSql = sSql & ", [" & v & "] LONG"
  Next
  sSql = sSql & ");"
  CurrentDb.Execute sSql
  RefreshDatabaseWindow

  ' CSV からテーブルへの読み込み
  For Each vDp In dic.Keys
    sSql = CSQL
    sSql = Replace(sSql, "{%1}", CTBL)
    sSql = Replace(sSql, "{%2}", "[" & Join(dic(vDp).Keys, "], [") & "]")
    sSql = Replace(sSql, "{%3}", vDp)
    sSql = Replace(sSql, "{%4}", CPATH)
    CurrentDb.Execute sSql
  Next
  Set dic = Nothing
End Sub
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
今すぐ実際に確認できる状況でなくなってしまったので、
後ほど試してみます。
取り急ぎお礼まで…。

この方法であれば応用が利きそうですね。
対象のCSVファイルは、2つだけではなく数百~数千程度になる予定ですので、
適宜修正して使わせていただきます。

お礼日時:2014/03/26 12:25

ファイルが二つだけであれば一旦個々にインポートしてから結合したほうが簡単。


テーブル名がそれぞれhoge1、hoge2 でインポートしたとすると
クエリのSQLビューに
(ユニオンクエリはデザインビューでは不可です)
select aaa,bbb,ccc,ddd,null as eee,null as fff from hoge1
union all
select aaa,bbb,null as ccc,ddd,eee,fff from hoge1
としたユニオンクエリを作成し保存、仮に「クエリ1」とします。

このクエリを基にテーブル作成クエリを作ります。
SQLビューでは
SELECT [クエリ1].* INTO hogex
FROM クエリ1;
となります。
このクエリを実行すると、hogex テーブルが作成されます。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
ファイルの数が少ない場合は、この方法で簡単にできそうですね。
しかし、実はファイル数が数百~数千単位になりそうで。。
説明が漏れており申し訳ありません。
一つの方法として参考にさせていただきます。

お礼日時:2014/03/26 12:20

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!