• 締切済み

Null文字が含まれるCSV(UTF-8)の読込

いつも参考にさせてもらっています。 よろしくお願いします。 受領したCSVファイルを1行ずつ取込み、加工して出力したいと思っています。 ファイル形式がUTF-8のため、ADODB.Streamを使って下記のように組みました。 -------------------------------------------------------------------------------- Sub testReadUTF8() Dim adoStIn As Object Dim varWork As Variant On Error GoTo ErrLBL: '読込用 Set adoStIn = CreateObject("ADODB.Stream") adoStIn.Charset = "UTF-8"          'Streamで扱う文字コードをutf-8に adoStIn.Open                 'StreamをOPEN adoStIn.LoadFromFile ("D:\test.csv")     'ファイルからStriamにデータを読み込む Do Until adoStIn.EOS             'Streamの末尾まで繰り返す varWork = adoStIn.readText(adReadLine)  'Streamから1行ずつ取込 '//処理~~~~~~ Loop ExitLBL: Exit Sub ErrLBL: 'エラー MsgBox Err.Description & vbCrLf & "(エラーコード " & Err.Number & ")", vbCritical End Sub -------------------------------------------------------------------------------- その際、 readText(adReadLine)  で取り出そうとしている行にNull文字(文字コード:00)が含まれる場合、 処理が固まってしまい、また、ErrLBLにも飛びませんでした。 読み込むCSVをテキストエディタでNull文字を除去したファイルは、正常に読込みができます。 ただし、Null文字の除去もVBAで同時に行いたく、 Replace関数でNull文字を除去すればよいかと、 ・varWork = Replace(adoStIn.readText(adReadLine), vbNullChar, "") ・varWork = Replace(adoStIn.readText(adReadLine), vbNullString, "") ・varWork = Replace(adoStIn.readText(adReadLine), Chr(0), "") ・varWork = Replace(adoStIn.readText(adReadLine), Chr$(0), "") と行ってみましたが、いずれも上記の部分で固まってしまいます。 何かしら、処理する方法はありませんでしょうか?

みんなの回答

  • ballville
  • ベストアンサー率47% (233/487)
回答No.7

ダメなCSVを次のpowershell ワンライナーで下処理してみては get-content ./bad.csv|%{$_ -replace "`0",""}|out-file ./repaired.csv

  • notnot
  • ベストアンサー率47% (4847/10258)
回答No.6

>バイナリモードにして、どのように扱えばよいのか、教えていただけますでしょうか? バイナリモードはバイナリデータなので行という概念が無いです。 テストしてませんが、バイナリモードで1バイトずつ読んで、vbNullcharと等しければスキップ、そうでなければバイナリモードで書くということでいいかと思います。

noname#232800
noname#232800
回答No.5

固定長の場合で、8ビット文字を扱える命令って peek、poke。Read、Writeでしたっけ。Unsigned Char 型。 可変長では7ビット。 scanf、printf。Char 型 今回のはReadTextではダメ

  • bardfish
  • ベストアンサー率28% (5029/17765)
回答No.4

まず、基礎的なことになりますがCSVってテキストベースでしょ? テキストファイルではNullはEOFとしてファイルの終端を表します。 テキストベースのCSVファイルでデータとしてNullを使用するのはご法度です。 それでも、そういうCSVファイルを扱う必要があるというのならば事前に加工しておきましょう。

OK_Akiko
質問者

お礼

bardfish様、ご回答ありがとうございます。 >テキストベースのCSVファイルでデータとしてNullを使用するのはご法度です。 そうなのです、こちらも想定外でした。 なので、加工もVBAでできないかなー、と思っておりました。

  • notnot
  • ベストアンサー率47% (4847/10258)
回答No.3

一度バイナリーモードで読んで、NUL文字を削除し、バイナリーモードで上書きして、それから改めてテキストモードで読んではどうでしょうか。

OK_Akiko
質問者

お礼

notnot様、ご回答ありがとうございます。 adodb.stream、バイナリーモードで処理できるのですね! 調査不足ですみませんでした。。。 試してみます!

OK_Akiko
質問者

補足

notnot様、すみません。。教えてください。 バイナリモードで1行読み取り、変数(string型かvariant型)に格納し、2桁ずつ読んでいって"00"だったら除去、と思っていましたが、誤りでした。 「バイナリモードで処理できる!」と喜びましたが、そもそも「バイナリモードで処理する」ということが分かっていませんでした。 ------------------------------ '読込用 Set adoStIn = CreateObject("ADODB.Stream") adoStIn.Charset = "UTF-8" 'Streamで扱う文字コードをutf-8に設定 adoStIn.Type = adTypeBinary 'Stream内のデータ型 adoStIn.Open 'StreamをOPEN adoStIn.LoadFromFile ("D:\test.csv") 'ファイルからStriamにデータを読み込む adoStIn.Position = 0 varWork = adoStIn.Read() ’//ここで、null文字(コード:00)なら除去する adoStIn.Close ------------------------------ としてvarworkに読み込んでみました。 想定では、varworkには、utf-8、BOMありなので、 CSVファイルの中身が ------------------------------ 12△45 ABCDE ------------------------------ だとすると、(△の部分が、null文字とする) ------------------------------ EFBBBF31320034350D0A41424344450D0A ------------------------------ と入ってくるのだと思い、"00"を処理すればよいと思っていたのですが、イミディエイトウィンドウで確認すると ------------------------------ ??2????? ------------------------------ と表示され、想定していた処理ではできないと分かりました。 バイナリモードにして、どのように扱えばよいのか、教えていただけますでしょうか?

  • HohoPapa
  • ベストアンサー率65% (454/690)
回答No.2

Chr(0)がファイルの途中に登場することを エクセルもVBA(諸々のメソッド)も想定していないだろうと思います。 思いつきですが、 1文字ずつ取り出して評価し Chr(0)を捨てる処理ならできそうです。 それが、次行以下のコードです。 Sub DelChr_0()  Dim adoStIn As Object  Dim varWork As String  Dim wkMoji As String    Set adoStIn = CreateObject("ADODB.Stream")  adoStIn.Charset = "UTF-8"  adoStIn.Open  adoStIn.LoadFromFile ("D:\test.csv")  varWork = ""    Do Until adoStIn.EOS   wkMoji = adoStIn.readText(1)   If wkMoji <> Chr(0) Then    varWork = varWork & wkMoji   End If  Loop    MsgBox (varWork)    '以下、必要ならvbCrLfでレコード分解 End Sub

OK_Akiko
質問者

お礼

HohoPapa様、ご回答ありがとうございます。 なるほど、一文字ずつですね! ファイルサイズが大きく、なるべくなら一括変換したかったのですが、 一文字ずつも検討してみます!

noname#232800
noname#232800
回答No.1

ヌル文字はテキストではなく、むしろEOFに相当すると思う。 CSVって事は、可変長でしょ? 固定長なら読み書きできると思う。

OK_Akiko
質問者

お礼

gobou_poo様、ご回答ありがとうございます。 バイナリエディタで確認したところ、1行の中に数文字Nullが入っていました。。。

関連するQ&A

  • UTF-8にエンコードされたCSVファイルをメモ帳で編集

    UTF-8にエンコードされたCSVファイルをメモ帳で編集しても文字コードはそのままなのでしょうか? 上記UTF-8コードCSVファイルをメモ帳で見ると、ちゃんと文字コード変換されてきれいに見えます。 編集作業として、レコード(行)の削除のみです。 よろしくお願いいたします。

  • 【VBA】保存したcsvファイルをメモ帳でUTFに変換する方法を教えてください。

    VBAの初心者です。 皆様のお力をお借りしたい次第です。 今私はデスクトップに保存したcsvファイルをUTFに変換し、 windowsメールでアドレスのインポートをしようとしていますが、 csvファイル自体をUTFに変換すると文字化けをしてしまうため、 メモ帳でUTFに変換→csv保存をしたいと思っております。 メモ帳をExcelから命令するにはどうしたらいいでしょうか? 以下はUTFに変換する際に使用させてもらったものです。 Dim JIS, UTF Set JIS = CreateObject("ADODB.Stream") JIS.Open JIS.Type = 2 JIS.Charset = "shift_jis" JIS.LoadFromFile "C:\~\JIS.csv" Set UTF = CreateObject("ADODB.Stream") UTF.Open UTF.Type = 2 UTF.Charset = "utf-8" JIS.CopyTo UTF UTF.SaveToFile "C:\~\UTF.csv", 2 JIS.Close Set JIS = Nothing UTF.Close Set UTF = Nothing

  • UTF-8のCSVファイルを開く

    エクセル2000でUTF-8の文字コードで作られたCSVファイルを開くと 文字化けしてしまいます。  文字化けせずに開く方法を御存知の方、教えてください。  VBAを使う方法でも構いません。(コードを教えてください。) 宜しくお願いします。 以上

  • VBAでUTF-8文字を読込、Excelに出力する方法

    タイトルの通りです。 簡単なプログラムを作ってみました。 このような事は出来ないのでしょうか。 教えてください。 宜しくお願いします。 ☆サンプルプログラム☆    ↓ Sub test() Dim Stm As Object Dim sText As String Const adCRLF = -1 Const adReadAll = -1 Const adTypeText = 1 sText = "あああ" Set Stm = CreateObject("ADODB.Stream") Stm.Open Stm.Charset = "UTF-8" Stm.WriteText sText ActiveSheet.Range("A1").Value = Stm.ReadText() Stm.Close Set Stm = Nothing End Sub

  • VBSで特定の文字で始まるファイルを開く

    VBSで"ADODB.Stream"オブジェクトを作成した場合、 LoadFromFileで開くファイルを指定するものだと思いますが、 このとき、特定の文字で始まるファイルを開く場合 どのように指定すれば良いのでしょうか? Set iSt = CreateObject("ADODB.Stream") ist.Charset = "UTF-16BE" ist.Open ist.LoadFromFile(?) オブジェクトがFileSystemObjectであれば *を使用してファイルを開くことができたのですが、 文字コードが"UTF-16BE"であるため ADODB.Streamを使うよう制限されています。

  • .Charset = "UTF-8"

    新しいテキスト ドキュメント.txtの中身は、 test テスト なのですが、 その中身をVBAで取得したく、 Sub Sample() Dim strList As String Dim adoSt As New ADODB.Stream Dim WSH As Variant Set WSH = CreateObject("Wscript.Shell") With adoSt .Type = adTypeText .Charset = "UTF-8" .Open .LoadFromFile (WSH.SpecialFolders("Desktop") & "\新しいテキスト ドキュメント.txt") Do While Not (.EOS) strList = .ReadText(adReadLine) Debug.Print strList Loop .Close End With End Sub と言うコードを作ったのですが、 返り値が文字化けしてしまいます。 test ?e?X?g が返ってきます。 .Charset = "UTF-8"が原因なのかもしれませんが ネットからコピペしたコードを使っている為 どのように変えればいいのかわかりません。 ご教授よろしくお願いします。

  • rubyの見えない文字

    こんばんは Ruby1.9.2のrails3.1.1を使用しています。 csvファイルをアップロードして、 data = param[:file].read.encode("UTF-8","UTF-8", :invalid => :replace, :undef => :replace, :replace => '').read.encode("UTF-8", :invalid => :replace, :undef => :replace, :replace => '?') のように読み込みまして、最初の1行の最初の要素が"code"でした。そこで、 data[0][0] == "code" としましたところ、falseが出力されました。両方とも文字コードはUTF-8で"code"なのですが、調査したところ data[0][0]length #=> 5 "code".length #=> 4 という違いが見つかりました。 この読み込みデータの見えない文字はなんなんでしょうか。 また、これを取り除く方法は何かありませんでしょうか。よろしくお願いします。 参考 data = param[:file].read.encode("UTF-8", :invalid => :replace, :undef => :replace, :replace => '').read.encode("UTF-8", :invalid => :replace, :undef => :replace, :replace => '?') としたところ、"???code"、長さ7という結果になりました。

  • (VBA )UTF-8(bom無)でテキスト書き出

    (VBA )UTF-8(bomu無し)でテキストファイルに書き出す 下記記マクロを使ってテキストファイルに書き出すとShift-JISになるようです。  下記コードを修正するとどのようになりますか ? ------------------------------------------------------------------ 'Chapterシートをテキストファイルへ書き出す Open "C:\Users\NOBU\Desktop\chap_Output.txt" For Output As #1 EndLow = WS2.Cells(Rows.Count, "A").End(xlUp).Row For I = 1 To EndLow Print #1, WS2.Cells(I, "A").Value Next Close #1 ------------------------------------------------------------------ 途中結果です。 UTF-8(BOM有)での書き出す方法はネットで探して  下記コードでうまく書き出し出来たのですが(BOM無し)の方法が良く分かりません。 以下が参考になりそうですが、修正の参考になりませんか ? http://www.asahi-net.or.jp/~ef2o-inue/vba_o/sub05_110_065.html ------------------------------------------------------------------------ 'ADODB.Streamオブジェクトを生成 Set ado = CreateObject("ADODB.Stream") 'ADODB.Streamで扱う文字コードを設定する ado.Charset = "UTF-8" 'ADODB.Streamを開く ado.Open '開いたADODB.Streamに内容を保管する 'adWriteLineは改行する時に入れる For I = 1 To EndLow ado.WriteText WS2.Cells(I, "A").Value, adWriteLine Next 'ADODB.Streamに保管されている内容をファイルに保存する ado.SaveToFile "C:\Users\Nubo\Desktop\chap_Output.txt", 2 'ADODB.Streamを閉じる ado.Close '終わったのが分かるようにメッセージを出す MsgBox "完了!" Set ado = Nothing End Sub

  • ADODB.Streamで開いたファイルに追記する

    VBScriptでCSVファイルをADODB.Streamを使って開き ファイルの最終行に1レコード追加する処理を行いたいのですが、 開く際に"追記"を指定することはできないようです。 (FileSystemObjectでは開く際に"追記"を指定することが出来ますが) CSVファイルの形式がUTF-16BEであるため ADODB.Streamを使用して開きます。 どのようにすれば追記が可能でしょうか?

  • PHPでCSVの読み込みができません。

    PHP4+ApacheでWebアプリケーション(問い合わせフォーム)を開発しています。 普段はApache+PHPを導入したWindowsマシンでコーディングしていて、CSVファイルも開きます。 しかし、開発サーバ(Linuxマシン、ApacheとPHPのバージョンは同じ)へアップロードすると Windowsマシンで読み込みができていたCSVファイルが読み込みができなくなります。 CSVファイルの文字コードShift-JISで各項目は""でくくってあります。1行あたり10項目で20行固定です。 CSVファイル読み込みする理由は定義ファイルとして読み込んむためで、各行には宛先や問い合わせ内容・タイトル等を設定し、定義ファイルの番号(3桁の数字)によって問い合わせフォームを切り替えています。 ちなみにPHPの文字コードはUTF-8です。 例) "f01","パソコンセミナー申込","","","","","","","","" "f02","インターネットに触れてみよう。","","","","","","","","" "f03","申込期限2009年1月末,"","","","","","","","" "f04","hoge@aaa.jp","hage@bbb.jp","debu@ccc.jp","","","","","","" "f05","support@ddd.jp","","","","","","","",""  :  : "f20","○○○","20","△△△","","","","","","" 1行目は問い合わせフォーム名、2行目と3行目はフォーム内容のコメント、4行目は担当者宛のメールアドレス、5行目は自動応答用のメールアドレス、6行目以降は問い合わせフォームの任意設定項目(f20の場合、○○○:好きな食べ物は?、20:文字数20文字、△△△:3つ以内で記入してください)を表します。 問い合わせフォーム本体PHPと入力チェック等を行う外部ライブラリPHPを用いています。現状は、本体PHPでCSVをfopenで開いて、CSV読み込みにはfgetcsv()を使用しています。指定行以内でループさせ、該当の行の該当項目を指定しています。 CSVファイルはテンプレートのCSVファイルをコピー関数で複製・リネームしていますが テンプレートファイル内の各項目(各行先頭項目)はしっかりコピーされています。 Windows環境下では mb_convert_encodingを使用して、読み込み・書き込み(Shift-JIS⇔UTF-8変換)ともに動いています。 しかし、Linux環境下では、まったく読み込みすらできません。 Linuxで読み込みができないのがどうしてもわかりません。 よろしくお願いします。

    • ベストアンサー
    • PHP

専門家に質問してみよう