質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.50%
VBA

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

Q&A

解決済

3回答

3818閲覧

ACCESSでCSVデータの集計

yuujiMotoki

総合スコア90

VBA

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

0グッド

0クリップ

投稿2018/09/27 00:22

#検討内容

アクセスを使って、下記のようなデータ読み出しをしています。
特急の依頼なので、至急に方向性を決める必要があります。

#####1)入力データ仕様

  • データはNo.CSVで保存されている。
  • データのmin,max列に、***.**m (単位はm) が含まれている

(例)INPUT

csv

1file name = "1.CSV" 2 3IMG000001 R# TP1 TP2 Min Max Result Actual 4IMG000001 R1 180 181 0.234 0.486 Pass 0.34366 5IMG000001 R2 167 169 0.2657 0.5521 Pass 0.39063 6IMG000001 R3 150 152 21.72m 71.22m Pass 0.03865 7IMG000001 R4 150 151 0.00m 24.01m Pass 0.00777 8IMG000001 R5 158 159 8.46m 49.10m Pass 0.022823 9IMG000001 R6 149 148 0.4855 1.02 Pass 0.6858 10IMG000001 R7 147 146 0.4678 0.9836 Pass 0.6544 11 12中略  R1-R64 (ここは可変) 13 14 15IMG000001 R62 95 89 0.733 1.318 Pass 0.8844 16IMG000001 R63 177 176 0.00m 19.99m Pass 0.00501 17IMG000001 R64 157 156 1.578 2.795 Pass 1.9316

#####2)要求内容

  • IMG000001列は不要なので除去する
  • ファイル名のNoを示すフィールドの列を追加
  • MSGBOXからのINPUTで、試験条件フィールドを1列追加(string)

#####出力データ仕様
(例)OUTPUT.csv

file name = "1.CSV"
file name = "2.CSV"

以下、300.csvぐらいまで続く

|No|R#|TP1|TP2|Min|Max|Result|Actual|
|:--|:--:|--:|
|1|R1|180|181|0.234|0.486|Pass|0.34366|
|1|R2|167|169|0.2657|0.5521|Pass|0.39063|
|1|R3|150|152|21.72m|71.22m|Pass|0.03865|
|中略|R4|〃|〃|〃|〃|〃|〃|〃|
|2|R1|180|181|0.234|0.486|Pass|0.34366|
|2|R2|167|169|0.2657|0.5521|Pass|0.39063|
|2|R3|150|152|21.72m|71.22m|Pass|0.03865|
|中略|R4|〃|〃|〃|〃|〃|〃|〃|

#####3)検討内容
現在はアクセスを使い、CSVデータの読み取りをVBAでマクロを書いています。

  • ファイルダイアログでフォルダを指定
  • フォルダの中の、CSVをDocmd.transfertextで読込
  • 読み込んだファイル名を入れる、テーブルFileNameをSQLで作成し、そこにINSERT
  • アクセス側でテーブル作成クエリを実施して、新テーブルを作成

VBA

1Function マクロ1() 2On Error GoTo マクロ1_Err 3Dim FD_PATH As Variant 4Dim fso As Object ' Scripting.FileSystemObject 5Dim csvfile As Variant 6Dim sName As String 7Const DefaultData As String = "DefaultData" 8 9FD_PATH = Get_Folder() 10DoCmd.SetWarnings False 11 12 Set fso = CreateObject("Scripting.FileSystemObject") 13 MsgBox fso.GetFolder(FD_PATH).Files.Count & "のファイルを取り込みますか?" 14 15 For Each csvfile In fso.GetFolder(FD_PATH).Files 16 17 On Error Resume Next 18 If csvfile Like "*.csv" Then 19 DoCmd.TransferText TransferType:=acImportDelim, _ 20 SpecificationName:="", _ 21 TableName:=DefaultData, _ 22 FileName:=FD_PATH & "\" & _ 23 csvfile.Name, _ 24 HasFieldNames:=True 25 26 sName = Replace(csvfile.Name, ".csv", "") 27 28 DoCmd.RunSQL "CREATE TABLE FileName(FILE CHAR(10));" 29 DoCmd.RunSQL "INSERT INTO FileName(FILE) VALUES('" & sName & "');" 30 31 End If 32 On Error GoTo 0 33 34 35 Debug.Print 36 37 Next 38 39 40 41マクロ1_Exit: 42 Exit Function 43 44マクロ1_Err: 45 MsgBox Error$ 46 Resume マクロ1_Exit 47 48End Function

###不具合
1.読込エラー

min,maxのデータに、*****mという文字列がはいっており、CSV読込をするとエラー(null)になる

csv

1IMG000001 R# TP1 TP2 Min Max Result Actual 2IMG000001 R1 180 181 0.234 0.486 Pass 0.34366 3 4 5                         floatで読み込みできない行がある 6IMG000001 R5 158 159 ** 8.46m 49.10m** Pass 0.022823

2.データ追加のためのルーピング

1ファイルを読み込んで、テーブルを作成して1ファイルのレコードを入れるところまでは出来たのですが、
その後のループの仕方で悩んでいます。

  • 都度、名前を変えて新テーブルを作っていくのがいいのか? 

 → この場合は、最後に1テーブルに合体させる必要あり

  • 同じテーブルに追加していくのか?

 → どんなSQLをかけばいいのか不明

sql

1SELECT FileName.FILE, 2DefaultData.[R# ], 3DefaultData.[TP1 ], 4DefaultData.[TP2 ], 5DefaultData.Result, 6DefaultData.Actual INTO NewDB 7FROM DefaultData, FileName;

#質問内容

  • 不具合1の改善方法
  • 不具合2の具体的方法

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

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

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

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

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

sousuke

2018/09/27 00:29

「特急の依頼なので~」などは回答者は知ったことではないので書かないほうがいいです。これを書いても早く回答が得られることはほぼありません。要件を伝えることに注力したほうが遥かに回答が早く得られると思います。
guest

回答3

0

データに例外が含まれているなら、ごちゃごちゃせずに、
VBAで、CSV1行を読込、変換等の処理、Accessに追加、と素直に処理しますね。

これなら、後から例外が増えたりしても、変更点は少なくて済むはずです。

また、FSOを使うより「Open FilePath For Input As #FileNum」等で
直接開いちゃった方が早かったと思います。

超特急でがんばってください~

投稿2018/09/27 06:57

ExcelVBAer

総合スコア1175

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

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

sazi

2018/09/27 07:11 編集

質問では、”*.csv”で読み込んでいるので、いきなりopenという処理は無理だと思います。 open使うかインポートにするかというのは正直悩むところではありますけど、項目の順番や文字区切り、区切り記号に関する部分でインポート系の方が気にするポイントが少なくて済むので、openはあまり使わないんですよね。
guest

0

ベストアンサー

愚直に一つずつcsvファイルを読み込んで、それを一行ずつデータベースに読み込めば良いと思います。テーブルはあらかじめ作成しましょう。その際m付きの値をDoubleに変換します。
以下にコードを載せます。参照設定で Microsoft Scripting Runtime を追加しています。
解決のヒントになれば幸いです。

vba

1 2Public Sub ImportCSVFiles() 3 Const DIR_CSV = "YOUR_CSVFILES_DIRECTORY" 4 Const MAX_CSV_FILENUM = 300 5 6 Dim DB As Database: Set DB = CurrentDb 7 Dim RS As Recordset: Set RS = DB.OpenRecordset("YOUR_TABLE") 8 9 Dim FileNum As Long 10 For FileNum = 1 To MAX_CSV_FILENUM 11 ImportCSVFile RS, DIR_CSV & "\" & FileNum & ".csv", FileNum 12 Next 13 14 RS.Close 15 DB.Close 16End Sub 17 18Private Sub ImportCSVFile(ByVal RS As Recordset, ByVal CSVFilePath As String, ByVal FileNum As Long) 19 Dim FSO As FileSystemObject: Set FSO = New FileSystemObject 20 Dim TS As TextStream: Set TS = FSO.OpenTextFile(CSVFilePath) 21 Dim Row As Variant 22 Do Until TS.AtEndOfStream 23 Row = Split(TS.ReadLine, ",") 24 RS.AddNew 25 RS!NO = FileNum 26 RS!R# = Row(1) 27 RS!TP1 = Row(2) 28 RS!TP2 = Row(3) 29 RS!Min = ConvMinMaxToDbl(Row(4)) 30 RS!Max = ConvMinMaxToDbl(Row(5)) 31 RS!Result = Row(6) 32 RS!Actual = Row(7) 33 RS.Update 34 Loop 35 TS.Close 36End Sub 37 38' 21.72m -> 0.02172 39Private Function ConvMinMaxToDbl(ByVal NumLikeStr As String) As Double 40 If NumLikeStr Like "*m" Then 41 ConvMinMaxToDbl = CDbl(Replace(NumLikeStr, "m", "")) / 1000 42 Else 43 ConvMinMaxToDbl = CDbl(NumLikeStr) 44 End If 45End Function

投稿2018/09/27 02:59

編集2018/09/27 06:25
hixtutokun

総合スコア21

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

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

yuujiMotoki

2018/10/30 02:28

参考になるソースを教えていただき、ありがとうございました。 お蔭様で、特急の依頼に間に合わせることが出来ました。
guest

0

1.読込エラー

Docmd.transfertextでインポートを行う際に作成されるテーブルのカラムの属性は、インポート元のデータ内容で決定されます。
先頭が数値型であれば数値型属性で定義されるので、読み進めて文字型があるとエラーが発生したりします。
インポート定義を指定して属性を明らかにしましょう。
基本、全て文字型のワークに取り込んで、変換するようにした方が、エラーチェックなども掛けられるので効率が良いかと思います。

また、accessではSQLでIN句を使用して外部ファイルをテーブルとして扱うこともできます。

2.データ追加のためのルーピング

同じテーブルに追加していく方が効率的です。

もし私が同じ処理を作成するなら、
※ワークテーブルは事前に定義
・IN句を使用したUNIONクエリーをワークテーブルにINSERTするSQLを動的に作成して実行。
・(必要であれば上記テーブルに対してエラーチェック)
・上記ワークテーブルから、目的のテーブルに型変換しながら追加/更新
みたいな処理で最初に試してみます。

投稿2018/09/27 01:14

編集2018/09/27 01:28
sazi

総合スコア25138

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問