• ベストアンサー

INPUT関数でのCSV読込がおかしい件

VisualBasic6.0で開発しております。 string型にて宣言した配列にシーケンシャルモードで 開いたCSVファイルを、 INPUT関数にて読み込んでいるのですが、" あああ" といったデータが、 配列に入ると"あああ "となってしまいます。つまり空白文字列が頭からお尻に移動してしまいます。 どなたか原因がわかる方、また回避方法がわかるかた は教えて頂ければ幸いです。なお、LINEINPUTではそのような現象はおこりません。しかしLINEINPUTは速度の観点から使いたくありません。 <参考ソース>   Type hairetu    a As String    b As String     ・     ・   End Type   Global 配列() As hairetu   dim intfile as integer   dim lngcnt as integer   intFile = FreeFile   Open "パス" For Input As #intFile   lngCnt = 0   Do While Not EOF(intFile)    redim preserve 配列(lngCnt)    Input #intFile, 配列(lngCnt).a,配列(lngCnt).b,・・・    lngCnt=lngCnt+1   LOOP

  • umeum
  • お礼率68% (22/32)

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

  • ベストアンサー
  • BlueRay
  • ベストアンサー率45% (204/453)
回答No.5

MSDNライブラリの「Input # ステートメント」を読んでみましたか? >ファイルからデータを読み込む場合、通常、文字列データは文字列型 (String)、数値データは数値データ型として格納されます。これ以外のデータを読み込んだ場合、次に示すようにデータによって変数に割り当てられる型が異なります。 >カンマのみ、または空白行 Empty 値 (VarType 0) このように記述されています。この辺の問題なのだと思われます。 で、対応方法です。 現在、CSV内データは只単にカンマのみで区切られていると思います。 AAA, 222, CCC,DDD,EEE ↓ "AAA"," 222"," CCC","DDD","EEE" 上段だと文字・数字を自動判別して質問のような問題になるので、下段の様に(")で囲って文字列にしてしまえば解決できると思います。 一案なので、参考になれば幸いです。

umeum
質問者

お礼

回答ありがとうございます 上記のMSDNは読みましたが、あまり考えていませんでした。勝手に型を認識してしまうんですね。。 CSVデータに手を入れるのはやや面倒でしたが、 ダブルコーテーションをつける事により解決 できました。 まことにありがとうございました

その他の回答 (4)

  • momoturbo
  • ベストアンサー率55% (49/88)
回答No.4

自分の場合も同じ現象が出ました。 ただし、空白文字は後ろには行かず 消えてしまいました。 Line Inputを使用するしかないのでしょうか? Split関数を使用すると簡単にカンマ区切りで 配列に落ちますけど、速度はどうなんでしょう?(^ ^; あくまで推測です。 Inputを使用すると空白文字のカット(Trim関数)が 入ってしまうのではないでしょうか?

umeum
質問者

お礼

回答ありがとうございます。 うーん環境によって現象が違うのでしょうか!? でも問題は起こるんですねやはり。 split関数は聞いたことはありましたが、使ってみようと考えた事はありませんでした。明日使用を検討してみようと思います。

  • kouta52
  • ベストアンサー率27% (32/116)
回答No.3

ちなみに構造体は、文字を固定にはしないのですか? Type hairetu    a As String * 5    b As String * 10 などです。 定義すれば、LSetを使えばできるのかなー? と思いました。

umeum
質問者

お礼

回答ありがとうございます 配列は現在、固定にもしています。この問題により 固定はやめていました。 Lsetなんて関数があったんですね。知りませんでした。明日試してみます。 ただ、現在、問題になっているのは" あああ "→"あああ  "となってしまうことなんです。 右よせ、左よせであれば配列に入れた後に文字列操作をすれば問題ないのですが、 真ん中だと前もしくは後ろに空白が何文字あるのかわからないんです。

  • momoturbo
  • ベストアンサー率55% (49/88)
回答No.2

CSVファイルの見直しをしてみてはいかがでしょう? カンマ・タブなどを見直して見てください preseveをとってしまうと配列が初期化されてしまったと 思うのですが、その辺のプログラムの修正は大丈夫なんでしょうか?

umeum
質問者

補足

回答ありがとうございます 大丈夫です。はじめにレコード数をカウントしてredim(レコード数)等として宣言しています。タブは入っていないようです。カンマも区切り以外のデータには使用していません。

回答No.1

> LINEINPUTは速度の観点から使いたくありません。 速度を問題にするなら、 > redim preserve 配列(lngCnt) 1回毎の配列の拡張のほうが罪ははるかに重いと言えます。 (ファイルの行数にもよりますが) 性能を悪化させるための故意の嫌がらせと受け取られても仕方がないでしょう。

umeum
質問者

補足

失礼致しました。 redim preserve 配列(lngCnt)はマイクロソフトより 指摘あり、redimを使用して既に速度改善済みになります。

関連するQ&A

  • Excelで作成されたCSVのVBでの読み込み

    いつもお世話になっております。 Excel2K、2002を使用しております。 Excelで作成されたCSVファイルをVBAで読み込もうと、以下の関数を作成しました。 Public Function CsvRead(ByVal FileName As String)   Dim IntFileNum As Integer 'ファイル番号   Dim TmpStr As String '   IntFileNum = FreeFile   Open FileName For Input As #IntFileNum 'CSVファイルのオープン   Do Until EOF(IntFileNum)     Input #IntFileNum, TmpStr     '     '~その他の処理~     '   Loop   Close End Function その他の処理中で特定の列に対し、特殊な処理を行う必要があるのですが ExcelでCSVファイルを作成する場合、16行単位でカンマの変動が起こりえますので、 http://support.microsoft.com/default.aspx?scid=kb%3Bja%3B400253 正確な列が取れません。 そこで1行読み込んでカンマで分解すればよいかと思い、 以下のように読み込んでみたのですが、、   Dim TmpStr() As String '   Dim LineStr As String   IntFileNum = FreeFile   Open FileName For Input As #IntFileNum 'CSVファイルのオープン   Do Until EOF(IntFileNum)     Line Input #IntFileNum, LineStr     TmpStr = Split(LineStr, ",")     '     '~その他の処理~     '   Loop 値にカンマが存在する場合も区切ってしまうので これも正しく取れませんでした。 値のカンマは区切り文字として判定せず、 正しく値を取得するにはどのようにすればよいでしょうか。 上記のことをふまえた判定をすべて行うしかないでしょうか。 ご教授のほど、よろしくお願いいたします。

  • VB6で特定フォルダのCSVファイルを指定して開く

     お世話になります。  ある株価を記すCSVファイルを読んで、配列格納しようと下記プログラムを書いてみましたが、 この状態では「読み込み対象のファイル」が「このVBプロジェクト」と同じフォルダに入っていなければならないようです。    そこで C:\IR_NK\USDJPY_20071010.csv の USDJPY_20071010.csv を読むというように、「別のフォルダのファイル」を読み込むように書き換えたいです。  この場合、どのように書けばいいか教えて欲しいです。 Private Sub C_FJU() Dim H_R(2) As Integer Dim HI_R(2, 8000) As String Dim intFileNo As Integer Dim strTextLine As String Dim strTxtDat As String intFileNo = FreeFile Open "USDJPY_20071010.csv" For Input As #intFileNo Do While Not EOF(intFileNo)  Input #intFileNo, strTextLine H_R(0) = H_R(0) + 1 HI_R(0, H_R(0)) = Trim(strTextLine) strTxtDat = strTxtDat & strTextLine & vbCrLf Loop T_HYO.Text = strTxtDat  Close #intFileNo End Sub

  • CSVから構造体へ代入

    お世話になります。 Private Type TestRecord Col1 As String * 255 Col2 As String * 255 Col3 As String * 255 End Type Sub ボタン1_Click() Dim FName As String Dim FileNo As Integer Dim LineData As String Dim TestRec() As TestRecord FileNo = FreeFile '選択したファイル名の取得 FName = Application.GetOpenFilename("CSV ファイル (*.CSV),*.CSV") If FName = "False" Then Exit Sub End If Open FName For Input As #FileNo Do Until EOF(FileNo) i = i + 1 Line Input #FileNo, LineData ReDim TestRec(i) TestRec() = Split(LineData, ",") Debug.Print buf Loop Close #FileNo End Sub ファイルの中身 "テストID1","テスト姓1","テスト名1" "テストID2","テスト姓2","テスト名2" 以上のコードを実行するとTestRec() =~の部分で型が一致しません とエラーが出てしまいます。 よき解決方法があれば教えてください。宜しくお願いします。

  • VB5でCSVデータをAccess97のDBへセット

    普段はVB.NETの開発をすこししているのですが VB5のプログラムの修正の依頼が来て困っています。 CSVのデータをVB5でAccess97のDBへデータセットしたいのですが VB.Netでは同様のプログラムを作成した事があるのですが VB5は全然仕様が違うので困っています。 VB5でCSVを読み込んで配列にセットするにはどのように したらいいのでしょか?CSVを行で読み込むところは なんとか調べてわかりましたが、VB5ではSplitや配列が使えそうに ないのでどのようにしたらいいのかわかりません。 よろしくお願いします。 現在のソース Dim strTextLine As String Dim strTxtDat As String intFileNo = FreeFile Open "c:\infile.csv" For Input As #intFileNo Do While Not EOF(intFileNo) Line Input #intFileNo, strTextLine Loop Close #intFileNo

  • CSVの読み込み処理について

    こんばんわです。 エクセルのVBAをつかってCSV形式のファイルデーターを読み込みように某サイトを参考に作成しました。 確かに読み込む事が出来たのですが、数値も文字列扱いになってしまいます。 数値処理する方法があるのでしょうか? Sub CSV_Read2() Dim FileType, Prompt As String Dim FileNamePath As Variant Dim textline, csvline() As String Dim Rowcnt, ColumNum As Integer Dim ch1 As Long FileType = "CSV ファイル (*.csv),*.csv" Prompt = "CSV File を選択してください" '操作したいファイルのパスを取得します FileNamePath = SelectFileNamePath(FileType, Prompt) If FileNamePath = False Then 'キャンセルボタンが押された End End If '空いているファイル番号を取得します ch1 = FreeFile 'FileNamePath のファイルをオープンします Open FileNamePath For Input As #ch1 'エラーが発生したらファイルを閉じます 'CSVのファイルは1行の項目数が正確に合っていないと読めないのですが、 '色々なCSVがあるようなので入れておきます On Error GoTo CloseFile '表の行番号の初期化 1行目から読み込んだデータを入力します Rowcnt = 1 Do While Not EOF(ch1) 'ファイルの終端かどうかを確認します。 '1行読み込みます Line Input #ch1, textline 'ダブルクォーテーションを削除します 'カンマ+ダブルクォーテーションで区切られている CSV ファイルなどは '適時追加してください textline = Replace(textline, """", "") 'カンマで分離します csvline() = Split(textline, ",") '配列渡しでセルに代入 Range(Cells(Rowcnt, 1), Cells(Rowcnt, UBound(csvline()) + 1)) = csvline() Rowcnt = Rowcnt + 1 Loop CloseFile: 'ファイルを閉じます Close #ch1 End Sub Function SelectFileNamePath(FileType, Prompt) As Variant SelectFileNamePath = Application.GetOpenFilename(FileType, , Prompt) End Function Function GetItemNum(FileNamePath) As Integer Dim ch1 As Long Dim textline As String '空いているファイル番号を取得します ch1 = FreeFile 'FileNamePath のファイルをオープンします Open FileNamePath For Input As #ch1 Line Input #ch1, textline '1行だけ読み込みます。 Close #ch1 GetItemNum = 1 '1行中のカンマの数を数えます Do GetItemNum = GetItemNum + 1 textline = Mid(textline, InStr(textline, ",") + 1) Loop Until InStr(textline, ",") = 0 End Function

  • 【ExcelVBA】FreeFile関数とGet関数について

    最近ExcelVBAを多用する部署に配属になり、現在勉強中の初心者です。 基本的な部分は何とか理解できるのですが、以下の部分がよくわかりません。 やっていることは、(FNAME)という名前のファイルにある数百万個の数値を、 R()という配列に格納しているらしいのですが、 "FreeFile"と"Get"の使い方がよく分かりません。 漠然とした質問で申し訳ありませんが、詳しい方教えてください。 Dim i As Integer, N As Integer Dim R(1 To 1000000) As Single Dim FNAME As String N = FreeFile Open FNAME For Binary As N For i = 1 To 10000 Get N, , R Next i

  • エクセルのCSV読み込みについて

    現在,以下の記述でエクセル上にマクロ実行ボタンを作成しました。 任意のCSVファイルをエクセルに取り込み利用する目的です。 実行ボタンを押すと,「実行時エラー ファイルにこれ以上データがありません。」として,記述中の 「Input #intFF, X(1), X(2), X(3), X(4), X(5), X(6), X(7) ' (2)」 部分が黄色になって止まってしまいます。 エクセル画面上には,希望通りのデータが出力されているようなので,このエラーが表示されなければデータの取り込みとしては問題ないのですが・・・。 どのようにこのエラーを回避し処理すればよいかかが分かりません。 どなたかご教示いただければ幸いです。 どうかよろしくお願いいたします。 Sub Macro4() ' CSV形式テキストファイル(7カラム)読み込みサンプル Const cnsTITLE = "テキストファイル読み込み処理" Const cnsFILTER = "CSV形式ファイル (*.csv),*.csv,全てのファイル(*.*),*.*" Dim xlAPP As Application ' Applicationオブジェクト Dim intFF As Integer ' FreeFile値 Dim strFileName As String ' OPENするファイル名(フルパス) Dim vntFileName As Variant ' ファイル名受取り用 Dim X(1 To 7) As Variant ' 読み込んだレコード内容 ' (1) Dim GYO As Long ' 収容するセルの行 Dim lngREC As Long ' レコード件数カウンタ ' Applicationオブジェクト取得 Set xlAPP = Application ' 「ファイルを開く」のフォームでファイル名の指定を受ける xlAPP.StatusBar = "読み込むファイル名を指定して下さい。" vntFileName = xlAPP.GetOpenFilename(FileFilter:=cnsFILTER, _ Title:=cnsTITLE) ' キャンセルされた場合はFalseが返るので以降の処理は行なわない If VarType(vntFileName) = vbBoolean Then Exit Sub strFileName = vntFileName ' FreeFile値の取得(以降この値で入出力する) intFF = FreeFile ' 指定ファイルをOPEN(入力モード) Open strFileName For Input As #intFF GYO = 1 ' ファイルのEOF(End of File)まで繰り返す Do Until EOF(intFF) ' レコード件数カウンタの加算 lngREC = lngREC + 1 xlAPP.StatusBar = "読み込み中です....(" & lngREC & "レコード目)" ' レコードを読み込む(このサンプルは7項目のCSV) Input #intFF, X(1), X(2), X(3), X(4), X(5), X(6), X(7) ' (2) ' 行を加算しA~G列にレコード内容を表示(先頭は2行目) GYO = GYO + 1 Range(Cells(GYO, 1), Cells(GYO, 7)).Value = X ' 配列渡し ' (3) Loop ' 指定ファイルをCLOSE Close #intFF xlAPP.StatusBar = False ' 終了の表示 MsgBox "ファイル読み込みが完了しました。" & vbCr & _ "レコード件数=" & lngREC & "件", vbInformation, cnsTITLE End Sub

  • ジャグ配列生成時の1オリジン

    ExcelVBAで、CSVFileを取込み、シートを介さずに 配列へ格納する処理をしています。 尚、一行のデータの数が変わる可能性があるため、 ジャグ配列にしています。  Dim FileNamePath As Variant 'CSVファイルパス  Dim CSVFile() As Variant  Dim ch1 As Long  Dim RowCnt As Long ~略~  ch1 = FreeFile  Open FileNamePath For Input As #ch1  RowCnt = 1  Do While Not EOF(ch1)   ReDim Preserve CSVFile(RowCnt)   Line Input #ch1, CSVFile(RowCnt)   CSVFile(RowCnt) = Replace(CSVFile(RowCnt), """", "")   CSVFile(RowCnt) = Split(CSVFile(RowCnt), ",")   RowCnt = RowCnt + 1  Loop ~略~ この時、後の処理でやりやすくするために配列の添字を 1からにしたく、行の添字となるRowCntを1としています。 同様に列となる添字も1からとしたくて、モジュールの宣言にて 「Option Base 1」としましたが、上記コードでジャグ配列を 生成すると、(多次元配列で言う)2次元目の添字は 0からとなってしまいます。  例:CSVFile(1)(0) このような状況で、ジャグ配列でも1オリジンとするには どのようにすれば良いのでしょうか。 宜しくお願い致します。

  • 配列について

    配列の要素数をinteger型にいれたいのですがどうしたらいいですか? 例   Dim A() As String   Dim B AS Integer       A = "あ","い","う" Aの要素数3をBに入れたいのです。 この配列の作りかたもあっているか分かりませんがよろしくお願いします。

  • VBAでCSVファイルを読み込もうとしていますが、

    VBAでCSVファイルを読み込もうとしていますが、 「ファイルが見つかりません」とエラーが表示されます。 どのように対処していいのかわかりません。 教えてくください。 Sub readCsv() Dim csvFile As String Dim ch As Integer Dim csvStr As String Dim str() As String Dim i As Integer Set ShellApp = CreateObject("Shell.Application") Set oFolder = ShellApp.BrowseForFolder(0, "フォルダ選択", 1) targetFolder = oFolder.Items.Item.Path Set fso = CreateObject("Scripting.FileSystemObject") Set fileList = fso.GetFolder(targetFolder).Files For Each file In fileList csvFile = file.Name ch = FreeFile Open csvFile For Input As #ch i = 1 Do While Not EOF(1) Line Input #ch, csvStr Close #ch str = Split(csvStr, ",") Range(Cells(i, 1), Cells(i, UBound(str) + 1)) = str i = i + 1 Loop Next End Sub

専門家に質問してみよう