• ベストアンサー

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 値にカンマが存在する場合も区切ってしまうので これも正しく取れませんでした。 値のカンマは区切り文字として判定せず、 正しく値を取得するにはどのようにすればよいでしょうか。 上記のことをふまえた判定をすべて行うしかないでしょうか。 ご教授のほど、よろしくお願いいたします。

  • 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() =~の部分で型が一致しません とエラーが出てしまいます。 よき解決方法があれば教えてください。宜しくお願いします。

  • 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

  • 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

  • 配列について

    配列の要素数を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

  • dimを使わずにredimを使う場合

    VBAを使っていて、 配列数を変数で定義したいのですが、 ネットで検索すると Dim aaaa() as integer Redim aaa(xxx, yyy) あるいは Dim aaaa() Redim aaa(xxx, yyy) as integer のようにdimで変数を定義した後にredimで定義しなおす方法が書かれてあります。 一方で、 Redim aaa(xxx, yyy) as integer のように、dimの定義を省略して、いきなりredimで配列を定義しても 問題なくプログラムは実行できることに気がついたのですが これら二つの方法に違いはあるのでしょうか? 後者を使っても問題ないでしょうか?

  • CSVの読み込みについて

    いつもお世話になります。 TextBox1に品物のコードを入れて、Label1に価格を表示するという簡単そうなものです。 品物のコードはCSVファイルのItem(1)から取得します。ところが存在しないコードを入力すると、 追加情報 : インデックスが配列の境界外です というエラーが出ます。下記ソースに何を追加すればよろしいのでしょうか?ご教授下さい。よろしくお願い致します。 Dim Reader As New IO.StreamReader("C:\XXX.csv", System.Text.Encoding.GetEncoding("Shift-JIS")) Dim Items() As String Dim Line As String = Reader.ReadLine       Dim Code As String 'コード Dim kakaku As String '価格 Do Until IsNothing(Line) Items = Line.Split(",") Code = Items(1) If HinCode = TextBox1.Text Then kakaku = Items(2) Label1.Text = kakaku Exit Sub End If Line = Reader.ReadLine Loop Reader.Close()

  • Excel2003VBA Variantについて

    教えてください。 下記にxのコードとyのコードとwのコードとを記載しました。 この内、 wのコード、xのコードでは(3)も含めノーエラーで終わるのですが、 yのコードでは(3)でエラーになってしまいます。 エラー内容は 「インデックスが有効範囲にありません。」 です。 どうしてでしょうか? ご教示をお願い致します。                記 Sub w() Dim B As Variant     ReDim B(1) '・・・(1)     ReDim B(5) '・・・(2)     ReDim B(10)     ReDim Preserve B(15) '・・・(3) End Sub Sub x() Dim B As Variant     ReDim B(1)     B = Split("B4:C15,D4:E15,F4:G15,B4:G15", ",") '・・・(1)     ReDim Preserve B(5) '・・・(2)     ReDim B(10)     ReDim Preserve B(15) '・・・(3) End Sub Sub y() Dim B As Variant     ReDim B(1) '・・・(1)     ReDim B(5) '・・・(2)     B = Evaluate("row(A1:A10)")     ReDim Preserve B(15) '・・・(3) End Sub                          以上

専門家に質問してみよう