過去の桐井戸端BBS (桐ver.8)
8884 改行コードを取り除く方法を教えてください hiroko 2000/12/12-16:25
こんにちは。桐V8SP6を使っています。

項目内の改行コードを取り除く方法を教えてください。

WEB上にあるFORMから入力されたデータがCSVファイルにS−JISで作成されます。
このCSVファイルを桐の表に取り込もうとしたところ、一つの項目に入力されたはずのデータが別のレコードとして読み込まれました。

データを見てみると、WEB上で改行して入力されているようで、CSVファイルにも次の様に作成されていました。

"XXXXXcrXXXXX","XXXXXcrXXXXX" ←crは改行コード

この場合、この改行コードを取り除く方法はありますでしょうか?

本来、桐の表へ取り込む前のデータ整備のお話なので、桐とは直接関係ないのかも知れませんが、宜しくお願いいたします。

8893 Re:改行コードを取り除く方法を教えてください Ogo 2000/12/13-00:26
記事番号8884へのコメント
>データを見てみると、WEB上で改行して入力されているようで、CSVファイル
>にも次の様に作成されていました。
>"XXXXXcrXXXXX","XXXXXcrXXXXX" ←crは改行コード
>この場合、この改行コードを取り除く方法はありますでしょうか?

CSV ファイルってデータベース的には始末におえないフォーマットですね
( K3 ファイルはマトモ)。

さて問題の改行コードですが、多分一括処理を組む必要があります。
実際に組むのは面倒なので、概念を述べます。
なお、ここでは最終的に桐に読み込んだ時に、桐のテーブル中で定義する
強制改行文字を仮りに「!」として記述します。
実際に使う際は、決して利用しない特殊な文字に置き換えて下さい。

0.1項目(文字型)だけの空の表(例.WORK.TBL)を準備する。
1. *.CSV ファイルを *.TXT にリネームする。
2.WORK.TBL に上記 *.TXT ファイルを読み込む。
3.以下を繰り返し、該当するデータがなくなれば終了。
  3−1.「”」(半角ダブルクォーテーション)が奇数個含まれる行
      を表の先頭から検索。※1
      該当データがなくなればループ脱出。
  3−2.その行から2行のみを選択(絞り込み)する。
  3−3.2行目のデータが1行目の文字列+”!”+2行目の文字列に
      なるように項目置換をかける。※2
  3−4.選択されたデータの内の先頭行のみを削除する。
  3−5.選択(絞り込み)を全解除して、3.の冒頭に戻る。
4.上記加工済みデータを読み込んだ *.TXT ファイルに上書き書き出し。
5.1.の逆に拡張子を *.CSV にリネーム。

※1. #条件選択(#文字数([])-#文字数(#文字置換([],"""",""))
   <>#INT((#文字数([])-#文字数(#文字置換([],"""","")))/2)*2,[],1,"")
   上記クォーテーションは全て半角ですので念の為。

※2.#条件選択(#直前値([],"")="",[],1,#直前値([],"")+"!"+[])
   上記クォーテーションは全て半角ですので念の為。


8894 Re:改行コードを取り除く方法を教えてください 遊び人 2000/12/13-05:57
記事番号8884へのコメント
>WEB上にあるFORMから入力されたデータがCSVファイルにS−JISで作
>成されます。このCSVファイルを桐の表に取り込もうとしたところ、一つの項目
>に入力されたはずのデータが別のレコードとして読み込まれました。

SP5以降は、CSVフォーマット内の改行(CR)にも対応しているようです。
読み込んだ場合、CRは強制改行文字に置き換えられます。
この際、リビジョンアップされてはいかがでしょうか。
8895 Re:改行コードを取り除く方法を教えてください hiroko 2000/12/13-09:03
記事番号8894へのコメント
Ogoさん。
ご親切に一括処理概要ありがとうございます。大変参考になりました。
早速、挑戦してみますね。複数の項目に改行コードが入ってた場合も大丈夫でしょうか?

遊び人さん。
私のバージョンは8、SP6なんですけど、CSVフォーマット内の改行(CR)に対応してくれませんよ。
別のレコードになってしまいます。
SP5とSP6で違うのかしら?

8896 Re:改行コードを取り除く方法を教えてください hidetake 2000/12/13-09:41
記事番号8895へのコメント
>私のバージョンは8、SP6なんですけど、CSVフォーマット内の改行(CR)に対応してくれませ
>んよ。別のレコードになってしまいます。SP5とSP6で違うのかしら?

試してみたところ項目内の改行で、SP6 で復帰(CR/0Dh) , 改行(LF/0Ah)の取り扱いは、
CSV ですと改行(LF) には対応しているようですが、通常の Windows(DOS) の改行(CR+LF/0Dh+0Ah) や、
MAC の改行(CR/0Dh) には対応していないようです。

8897 Re:改行コードを取り除く方法を教えてください hidetake 2000/12/13-10:14
記事番号8896へのコメント
>WEB上にあるFORMから入力されたデータがCSVファイルに
>S−JISで作成されます。

このフォームのデータを受けとった処理はどうされています?
ひょっとして、単に文字コード変換しただけで改行の統一化が計られてないと、
書き込まれたプラットフォームにより、改行もいろいろな形式で送られてくるかも知れません。

改行には UNIX(LF) , Windows&DOS (CR+LF) , MAC(CR) と環境により取り扱いが異なるわけですが、ブラウザから書き込んだ場合も Windows から書き込めば CR+LF が送られるようです。

掲示板などだと、フォームからデータを受けとった段階で文字コード変換するとの同時に改行も処理します。
例えばCGI (perl) だと

$Value =~ s/\r\n/<br>/g;
$Value =~ s/\r/<br>/g;
$Value =~ s/\n/<br>/g;

と言うようにしますが、この段階を操作できるのなら、桐側で対処するより簡単です。

$Value =~ s/\r\n//g;
$Value =~ s/\r//g;
$Value =~ s/\n//g;

と言うように、全てのプラットフォームの改行を取り去ってしまえば良いだけです。


8899 Re:改行コードを取り除く方法を教えてください Ogo 2000/12/13-11:36
記事番号8897へのコメント

>と言うように、全てのプラットフォームの改行を取り去って
>しまえば良いだけです。

「改行を取り去って」でいいのかなぁ〜? (^^;;

8900 Re:改行コードを取り除く方法を教えてください Ogo 2000/12/13-11:51
記事番号8895へのコメント

>複数の項目に改行コードが入ってた場合も大丈夫でしょうか?

"(半角クォーテーション)が奇数個であるということと、
一度に全データを置換せずに、毎回先頭から検索して発見できた最初のレコード(と次のレコード)のみを処理対象にするということがミソです。

- - -

最初に見つかった "(半角クォーテーション)が奇数個であるレコードは、必ず「改行コードが入っているレコードの先頭ブロック」です。

複数の項目に改行コードが入っている場合は、次行の "(半角クォーテーション)の数は必ず偶数個になり、そうでなければ必ず奇数個になります。

しかし、先頭行のみを処理することにより(尚且つ処理後の先頭ブロックの不要データを削除した後、
一旦は選択(絞り込み)を解除してから改めて奇数個のレコードを検索する)、次に見つかる筈の「改行コードが入っているレコードの先頭ブロック」とは、

複数の項目に改行コードが入っていた場合は、最初に見つかったレコードの第1ブロック+第2ブロックになるはずです。

もちろん、1項目にのみ改行コードが入っていた場合は、次の「改行コードが入っているレコード」が検索されるはずですね。

- - -

従って、1行処理する毎に選択(絞り込み)を解除して毎回先頭から処理対象行を検索することにより、
本来の1レコードに幾つ改行コードが含まれていようと、何も問題がなく処理が終了するはずです。

8901 Re:改行コードを取り除く方法を教えてください hidetake 2000/12/13-11:54
記事番号8899へのコメント
>「改行を取り去って」でいいのかなぁ〜? (^^;;

元が取り去るだから、取り去るだけど、桐の強制改行文字、もしくは LF にしても良い!

フォームだから、ここで書き出されるデータは、1軒に付き1行ですよね!
その後に、複数のフォームで出力されたデータを複数のレコードにまとめるかは別の問題
だけど、何か問題があるのでしょうか?


8905 Re:CSV ファイルのフォーマット Ogo 2000/12/13-21:21
記事番号8900へのコメント
現在、別所で hidetake さんと CSV ファイルについて話を続行しています。

問題は「項目内改行」と「レコード末」をどう区別するかという点に絞られます。

項目内改行がある場合、これをレコード末と区別するためには、
その当該項目値は必ず半角ダブルクォーテーションで囲むルールになっているので、半角ダブルクォーテーションが奇数の場合、
これは項目内改行が存在するレコードである――というのが私の前提です。
(半角ダブルクォーテーションが文字型の項目値として含まれる場合、 K3 ファイル同様に """ とか """" とかの文字列に直されている)

しかし、 hidetake さんの話では、 CSV ファイルの定義では、項目内改行が存在しない場合でも、
1レコード内の半角ダブルクォーテーションが奇数の場合が存在し得るのではないか――ということです。

このカラクリは、即ち「項目内改行」と「レコード末」を半角ダブルクォーテーションで囲む以外の方法で判別できるなら、
項目内改行を半角ダブルクォーテーションで囲まなくてもレコード末と区別できるので、本当に文字列としての
半角ダブルクォーテーションのみをそのまま書き出しても問題は発生しない(つまり、1レコード内の全項目のデータの中に
半角ダブルクォーテーションが奇数個存在す
る形で書き出しても問題が発生しない)ということです。

で、現実に「項目内改行」と「レコード末」を半角ダブルクォーテーションの有無以外の理由で判別できる仕組みをエクセルは採用しているのです(ただし、半角ダブルクォーテーションで囲むという変換も同時に行なっていますが)。

更に問題なのは、
1.アクセスではこのエクセル流の判別方法を採用してはいないこと。

2.今回みたいに WEB のフォームからポストされたデータ
  の場合、項目内改行や半角ダブルクォーテーションが
  文字列データに含まれている場合に、生成される CSV
  ファイルの定義は CGI の実装次第で、エクセル流にも
  アクセス流にも、第3のパターンにも(エクセル流の
  項目内改行を採用していながら、項目値を半角ダブル
  クォーテーションで囲まない)できる。

すなわち、 CSV というファイルのフォーマットは上記3種類が許容されていて、どんなデータなのかは実データで試してみない限り
予想できないということです。

続く

8906 Re:CSV ファイルのフォーマット Ogo 2000/12/13-21:57
記事番号8905へのコメント
>問題は「項目内改行」と「レコード末」をどう区別するか
>という点に絞られます。

さて、そのカラクリですが。
インターネットでいろいろやっている人は当然ご承知だと思いますが、「改行コード」のは3種類有ります。

1つは UNIX 系が採用している x0A (LF)
これは本来「ラインフィード」を意味し、「次行に制御を移す」という意味です。

1つは Macintosh が採用している x0D (CR)
これは「キャリッジリターン」を意味し、「行頭に制御を移す」という意味です。

実は MS-DOS / Windows では 改行コードは x0D0A (CR+LF)という複合コードなのです。
つまり、制御を行頭に移してから次行に移動するという動作をご丁寧に全指定しているのです。

生の MS-DOS コンソールで、エスケープシーケンス等を使ってスクリーン制御を行なった事がある人は知っている筈です。
x0D (CR) のみを発行すると今の行位置がそのままで行頭に制御(カーソル)が動きます。
x0A (LF) のみを発行すると桁数がその位置のままで次行に制御(カーソル)が動きます。
これが MS-DOS / Windows の仕様なのです。

ところが、エクセルの書き出す CSV ファイルでは、項目内改行は「x0A (LF)のみ」だったのです(アクセスは x0D0A (CR+LF))。
従って、エクセルで書き出された CSV ファイルの項目内改行のコードはアクセスに取っては青天の霹靂で、
理解できない異常コードとして表示されるという馬鹿げた仕様になっています。

さぁ、こんなことが許容されるなら、改行コードの種類によって
項目内改行とレコード末は区別できるはずなのですから、
ここを半角ダブルクォーテーションで囲む必要はないと言えますね。
ということは、「文字列項目値の1部としての半角ダブルクォーテーション」は何の加工もしなくてそのまま書き出したとしても
("" とか """ とか """" とかに変換しなくても)問題が発生しない筈と強弁できるわけです。

さすがMSが世界に普及させる仕様だけあります。

「改行コードはx0D0A (CR+LF)」と決めている MS-DOS / Windowsのテキスト環境において、「x0A (LF) のみ」というのは
バイナリデータです(アクセスでさえもそのままでは対応できない)。
これを正しく処理できなくても、そんな仕様でデータを書き出す側に非がある――と言ってもムダで、
全世界の普及量はエクセルの方が圧倒的に多いのです。

現実には、エクセルは項目内改行を書き出す時は半角ダブルクォーテーションで値を囲むようですし、それに連動するため、
文字列項目値の一部に半角ダブルクォーテーションが含まれる場合には "" とか """ とか """" とかに変換する仕様になっています。

アクセスは項目内改行の文字コードがエクセルと違うのみです。

つまり、この2つのアプリケーションが書き出した CSV ファイルならば、多分、私が書いた手順で処理すれば大丈夫でしょう。

しかし、これ以外の場合は検証が必要です。
問題は「項目内改行の文字コード」(バイナリエディタで確認する必要がある)と
「文字列項目値の1部としての半角ダブルクォーテーションの変換の有無」です。


8907 Re:CSV ファイルのフォーマット Ogo 2000/12/14-00:04
記事番号8906へのコメント
さて、まとめてみます。

CSV ファイルでは、その様式が3種類有り得ます。

1.「項目内改行」の文字コードが「x0A (LF) のみ」で、
  項目内改行を含む項目値を半角ダブルクォーテーションで囲む。
  これに伴い、項目値として半角ダブルクォーテーションを文字
  として含む場合には、K3ファイル同様の2重化した文字列に
  置換する。――【エクセル方式】
2.「項目内改行」の文字コードが「x0D0A (CR+LF)」で、
  項目内改行を含む項目値を半角ダブルクォーテーションで囲む。
  これに伴い、項目値として半角ダブルクォーテーションを文字
  として含む場合には、K3ファイル同様の2重化した文字列に
  置換する。――【アクセス方式】
3.「項目内改行」の文字コードが「x0A (LF) のみ」で、
  項目内改行を含む場合も工夫なし。
  項目値として半角ダブルクォーテーションを文字として含む場合も、
  工夫なしでそのまま書き出す――【第3方式】

なお、項目値として半角コンマを文字として含む場合、1.2.はその文字列全体を
半角ダブルクォーテーションで囲むだけで対応できるが、3.の場合は何かしらの置換が必要になる。

1.に関しては、どうも 桐 Win は上記 1.のエクセル方式のみをサポートしているのではないかと思われ、
そうだとすれば、単に桐 Win に取り込むだけで問題なく変換できる( #8894 で言っているのはこのこと――
しかし、x0A (LF) の項目内改行コードは、変換だと強制改行文字に変換されずに半角スペースになる。――
ファイル属性で強制改行文字を設定してある既存のテーブルに「読み込み」を行なった場合は、
項目内改行コードは強制改行コードに変換される)。

多分、2.は私が #8893 で書いた手順で大丈夫と思われる。
(この件について重大な問題アリ。後述)

1.が 単純変換 や #8893 の手順でうまく行かないケースとか、3.のケースとかは、
少なくともバイナリレベルでのコード置換を行なわない限り、桐のみの処理ではどうにもならないように思う。

なお、勝手なフォーマットのコンマ区切りテキストファイルを拡張子 CSV にしているだけなら、どうすりゃいいかは判らない。

8908 アクセス流 CSV ファイルの取込破綻 Ogo 2000/12/14-00:15
記事番号8907へのコメント
>多分、2.は私が #8893 で書いた手順で大丈夫と思われる。
>(この件について重大な問題アリ。後述)

実際に試してみて驚嘆すべき事実が判った。

桐 Win で テキスト読み込みで *.txt ファイルを読み込んだ場合、
半角ダブルクォーテーションは当然そのままの文字として読み込まれるものだと思っていました。

ところが、あにはからんや、*.txt をテキスト読み込みした結果は *.csv を CSV 読み込みした結果と同一だった。 (-o-)
(更に言うなら、拡張子を K3 にして K3 読み込みした結果も同じだった)

一体なんて仕様なんだ。何考えてんだ。>K3

別の方法を模索してみよう。 (-o-)

8910 Re:アクセス流 CSV ファイルの取込方法 Ogo 2000/12/14-01:10
記事番号8908へのコメント
>ところが、あにはからんや、*.txt をテキスト読み込みした
>結果は *.csv を CSV 読み込みした結果と同一だった。 (-o-)

つまり、勝手に半角ダブルクォーテーションが消えている項目がたくさんあるわけです。

しかも桐5でも同じ仕様だと判って尚更ショック。
こりゃ桐はテキストデータ処理には使えんわ。

ということで、どうしても桐に読み込むためには、別途のツール(ソフト)が必須となります。

なお、ここでは最終的に桐に読み込んだ時に、桐のテーブル中で定義する強制改行文字を仮りに「!」として記述します。
実際に使う際は、決して利用しない特殊な文字に置き換えて下さい

0.1項目(文字型)だけの空の表(例.WORK.TBL)を準備する。
  この表には強制改行文字を定義してはいけません。
1. *.CSV ファイルを *.TXT にリネームする。
2.テキスト置換ツールを使って、「"」(半角ダブルクォーテーション)
  を「!」に置換して、上書き保存終了します(もちろん単にテキスト
  エディターに読み込んで置換してもいいです)。
3.WORK.TBL に上記 *.TXT ファイルを読み込む。
4.WORK.TBL の「!」を項目置換で「"」(半角ダブルクォーテーション)
  に文字置換する。※1
5.以下を繰り返し、該当するデータがなくなれば終了。
  5−1.「"」(半角ダブルクォーテーション)が奇数個含まれる行
      を表の先頭から検索。※2
      該当データがなくなればループ脱出。
  5−2.その行から2行のみを選択(絞り込み)する。
  5−3.2行目のデータが1行目の文字列+”!”+2行目の文字列に
      なるように項目置換をかける。※3
  5−4.選択されたデータの内の先頭行のみを削除する。
  5−5.選択(絞り込み)を全解除して、5.の冒頭に戻る。
6.上記加工済みデータを読み込んだ *.TXT ファイルに上書き書き出し。
7.1.の逆に拡張子を *.CSV にリネーム。

※1.#文字置換([],"!","""")

※2.#条件選択(#文字数([])-#文字数(#文字置換([],"""",""))
  <>#INT((#文字数([])-#文字数(#文字置換([],"""","")))/2)*2,[],1,"")

※3.#条件選択(#直前値([],"")="",[],1,#直前値([],"")+"!"+[])

ちなみに、テキスト置換ツールは
http://www.vector.co.jp/vpack/filearea/win95/util/text/conv/
にいくらでもあります。

#ホンマに大丈夫かなぁ〜? だんだん不安になって来る。 (^^;

8911 Re:改行コードを取り除く方法を教えてください 遊び人 2000/12/14-06:39
記事番号8895へのコメント

>私のバージョンは8、SP6なんですけど、CSVフォーマット内の改行(CR)に対応してくれませ
>んよ。別のレコードになってしまいます。SP5とSP6で違うのかしら?

あっ。そうですか。LFだけだったですか?…。
プアーな話。改善要求だすべきでしょうね。

8912 Re:改行コードを取り除く方法を教えてください hiroko 2000/12/14-11:19
記事番号8911へのコメント
みなさん、こんにちは。hirokoです。
いろいろと、皆さんご親切にありがとうございます。

私の方でも各OSでの改行コードを調べてみました。
各OSでの改行コードは、Windowsが「CR」+「LF」、Macが「CR」、UNIXが「LF」になっていました。

WEB上のCGI(Parl5)で改行コードを取り除くという方法もあったのですが、
入力されたままのデータを使いたかったものですから、何とか方法がないものかと悩んでいました。

一旦、Accessにテキスト型で読み込み、CSVに書き出すと、うまくできたりもしました。
しかし、今ひとつ不安で、皆様に教えて頂いた次第です。

皆さんご親切にありがとうございます。

8913 Re:改行コードを取り除く方法を教えてください hidetake 2000/12/14-11:38
記事番号8912へのコメント
もし、頻繁に使うと言うことであれば、ODBC の設定でシステムDSN にでも、
その CSV を Text ドライバで登録して置き、
そのデータを、桐の外部DB で読み込むようにしておくと、
外部DB で読み込んだ後、必要なテーブルに表書き出しでデータを移すことも可能です。

ただ、項目内改行の CR / LF / CR+LF も、そのまま桐内に取り込まれるので、
必要であれば、置換 []=[]等行う必要があるかも知れません・・・


戻る