[[20130701135347]] 『固定長データの取り込み』(たけちゃん) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『固定長データの取り込み』(たけちゃん)

 以下のような固定長のデータの取り込みを行った際、
 半角スペースが勝手に削られてしまいます。
 データ形式を文字列にしても結果は同じです。

 スペースも含めてデータですので、非常に困っています。
 これはExcelの仕様で、どうしようもないことなのでしょうか?

 何かいい手があれば教えて下さい。よろしくお願い致します。

 <Windows XP, Excel2007>

 <元の固定長データ>
 123あいう____ABC_
 456えおかき__DEFG

 注1)"_" は、半角スペース
 注2)区切り位置は以下の3箇所
   (1) 3バイト目と 4バイト目の間(1レコード目なら"3"と"あ"の間)
   (2)13バイト目と14バイト目の間(1レコード目なら"_"と"A"の間)
   (3)17バイト目の後(1レコード目なら"C"の後の"_"の後)

 <取り込み後のデータ>
 A列   B列   C列
 −−−−−−−−−−
 123   あいう  ABC
 456   えおかき DEFG

 ↑結果、全てのスペースがなくなります。


 生データを貼り付けて関数で処理してみては?

 A1にデータ

 B1 =LEFTB(A1,3)
 C1 =MIDB(A1,4,13)
 D1 =MIDB(A1,17,100)

 (GobGob)


 有難うございます。
 やはり取り込み時に一発では無理ですか?

 そもそも何故、どういう考えの基、Excelは勝手にスペースを削ってしまうのでしょうか?

 (たけちゃん)

 ※勘違いで削除。。。

 区切り位置のスペースが勝手に削除されるね。。。

 Excel2003以前は残ってたような。。。。

 なんでだろうね?

 (GobGob)

 固定長にするための(データとしては不要な)スペースとして扱うから
 削除するのでしょう。

 <元の固定長データ>
 123,あいう____,ABC_
 456,えおかき__,DEFG
 カンマで区切ればスペースは残ります。
 (cai)

 有難うございます。

 この場合、データとして不要ではありません。スペースも含めてデータです。
 Excelは何故勝手に不要と判断するのでしょうか?
 ここが分かりません。

 また、基のデータは普通の固定長データですので、カンマ区切り等はできません。


 実際の作業ではスペースが必要な場合も不要な場合もあり得ます。
 マイクロソフトは、不要な場合が多いと判断したのでしょう。
 (cai)

 Excelは数値を扱うソフト→数値に空白が付いていては数字になってしまって困る→空白はいらないもの

 ということらしい。
 じゃあ文字にはつけとけよor残すかどうか聞いてこいよ、と思うけどね。

 つーわけでExcel君の取り込み機能だけでは空白のこすのは無理と思われ。
 caiさんのようにテキストファイルの時点でカンマを追加するか、
 テキストファイルの空白を _ にでも置き換えをして、Excel上で取り込んだ後に空白に置き換えをするか。
 またはマクロでくむか。

 多分どれかじゃないかなあ?
 (1111)


 有難うございます。

 取り込み時での処理は諦めます。
 でもやはり、おっしゃるとおり、スペースの削除(する or しない)の設定は欲しいです。

 マイクロソフトは、不要な場合が多いと判断か・・・勝手に判断すなっちゅーねん!

 (たけちゃん)


 対象テキストファイルをデータベースとみなして、接続ファイルを作成することで
 ご希望のデータをテーブルとして、作成することはできます。

 最初に接続ファイルを作るのは、
 SQLも必要なので、DBの知識がないとちょっと大変ですが、
 一度作成してしまえば、次回からは、その接続ファイルを呼び出すことで簡単に
 ご希望のデータ分割(空白も含んだデータ)が行えます。

 「データ」----「その他のデータソース」----「データ接続ウイザード」で
 接続ファイルを作成します。

 参考までに

 ichinose


 有難うございます。

 「データ接続ウイザード」を起動してみましたが、
 どうやって使うかさっぱりです。
  そのうち勉強しようと思います。

 またの機会、よろしくお願いします。

 (たけちゃん)


 > またの機会、
 とりあえず閉じられたのかもしれませんが、データベースとして読む話が出てきましたので、
 関連して、ランダムアクセス・ファイルとして固定長テキストを読む方法です。

 ----+----+----+----
 123あいう____ABC_↓
 456えおかき__DEFG↓
のように バイト数が決まっていれば、それをモジュールの先頭で Type文で宣言しておけば
1行づつ(1レコードづつ) 読み込むことはできます。

 '----------------------------------------------------------- 標準モジュール
 Option Explicit

 Type OneRecord
    cod(1 To 3) As Byte   ’最初の3バイト
    nam(1 To 10) As Byte  ' 次の10バイト
    ext(1 To 4) As Byte   ' 最後の 4バイト
    b2(1 To 2) As Byte    '改行コード(CR+LF 2バイト分)
 End Type

 Sub Try2()
    Dim Filename
    Filename = Application.GetOpenFilename( _
        "固定長テキスト,*.txt;*.prn")
    If VarType(Filename) = vbBoolean Then Exit Sub

    Dim io%
    Dim rec As OneRecord
    Dim i&, n&, b&
    io = FreeFile()
    Open Filename For Random As io Len = Len(rec)
    b = LOF(io)  '全バイトサイズ
    If b Mod Len(rec) > 0 Then
        MsgBox "レコード長が定義と一致しません"
        Close io
        Exit Sub
    End If
    n = b \ Len(rec)
    ReDim dat(1 To n, 1 To 3)
    For i = 1 To n
        Get #io, , rec 'i番目のレコードを読み込む
        With rec
            dat(i, 1) = StrConv(.cod, vbUnicode)
            dat(i, 2) = StrConv(.nam, vbUnicode)
            dat(i, 3) = StrConv(.ext, vbUnicode)
        End With
    Next
    Close io

    '新規シートに読み込み結果を表示
    With Worksheets.Add(After:=Worksheets(Worksheets.Count))
        .[A1].Resize(n, 3).Value = dat
    End With

 End Sub
 (kanabun)


データベース接続では、最後の空白が拾えませんでしたので、
没案です。

ichinose


 みなさん、有難うございます。

 kanabun さんのマクロ、実行しました。
 うまくいきました。こんな方法もあるのですね。

 ただ、数字の後のスペースはなくなっちゃうのですね。
 その方が自然と言えば、それまでなのですが。
 数字の後のスペースを生かすのは無理なのでしょうか?
 前もって、該当のセルの表示形式を文字列にしていても
 無駄でした。

 (たけちゃん)


 > ただ、数字の後のスペースはなくなっちゃうのですね。

 それは、VBAではなく、Excelシートの都合です。
 元データはちゃんとスペースなど保持してますから。

 必要に応じて、シートに展開される前、Excelに「それは文字列だよ!」と
 教えてあげればよいのです。(NumberFormatもしくは、NumberFormatLocal)

 (Abyss)

 >最後の空白が拾えませんでしたので、没案です。
 固定長なのですから、拾えないなら、文字列長を調べて空白を補う という方法もありますねえ
 既にVBAでの解決方法がでていますので、参考程度に後程、データベース接続案で再挑戦しようかと思います。
 SQLが長くなるのであんまりよい方法とは言えませんが・・・。

 ichinose

 NumberFormatLocal を使用してやってみました。

 数字の部分も確かに表示形式は文字列(左詰め)になりましたが、
 やはり後ろのスペースは削られてしまいます。
 どうすれば、数字の後のスペースを残せるでしょうか?

 (たけちゃん)


 > どうすれば、数字の後のスペースを残せるでしょうか?

 修正ついでに、別案です

    ReDim dat(1 To n, 1 To 3) As String  '◆データ型を明示
    For i = 1 To n
        Get #io, , rec                   ' i番目のレコードを読み込む
        With rec
            dat(i, 1) = "'" & StrConv(.cod, vbUnicode)  '先頭にアポストロフィーをつける
            dat(i, 2) = StrConv(.nam, vbUnicode)
            dat(i, 3) = StrConv(.ext, vbUnicode)
        End With
    Next

   (kanabun)


 NumberFormatLocal で表示形式を設定し、
 ReDim dat(1 To n, 1 To 3) As String で データ型を明示することによって、
 先頭のアポストロフィーは不要で、思ったとおりの結果が得られました。

 私的には、これで十分満足です。

 kanabunさん はじめ、皆さん有難うございました。

 (たけちゃん)


 123あいう____ABC_
 456えおかき__DEFG

 上記のようなデータ(_は、半角空白)がd:\aaa\bbb\sample.txt

 というファイルに格納されているとします。

 改行コードを除いて、17バイトの固定長データです。

 このファイルに接続して、Excelシートには、

  A      B       C
 123     あいう____    ABC_
 456     えおかき__    DEFG

 3Byte     10Byte     4Byte

 分割することを考えます。

 リボンの「データ」----「その他のデータソース」----「データ接続ウィザード」とクリックし、
 「データ接続ウィザード」ダイアログを表示させます。

 接続するデータソースとして、「その他/詳細」を選択し、「次へ」ボタンをクリックします。

 「データリンクプロパティ」ダイアログが表示されます。

 プロバイダータブにて、「Microsoft Jet 4.0 OLE DB Provider」を選択しください。

 選択した状態で 「すべて」タブをクリックしてください。

 「Data Source」を選択して、「値の編集」をクリックしてください。

 プロパティの値として、 d:\aaa\bbb  sample.txtのあるフォルダパスを指定してOKボタンをクリックしてください。

 「Extended Properties」を選択して 、「値の編集」をクリックしてください。

 プロパティの値として、 TEXT;HDR=NO;  と指定してOKボタンをクリックしてください。

 「データ接続ウィザード」ダイアログに戻りますから、「完了」ボタンをクリックしてください。

 「データインポート」ダイアログが表示されます。

 「データを返す先」を =$A$1 と指定し、「プロパティ」ボタンをクリックしてください。

 「接続プロパティ」ダイアログが表示されます。

 「定義」タブをクリックしてください。

 コマンド文字列として、既定で sample#txt と表示されているはずですから、これを

 select iif(isnull(f1),space(3),strconv(midb(strconv(f1,128),1,3),64) & space(3-lenb(midb(strconv(f1,128),1,3)))),
iif(isnull(f1),space(10),strconv(midb(strconv(f1,128),4,10),64) & space(10-lenb(midb(strconv(f1,128),4,10)))),
iif(isnull(f1),space(4),strconv(midb(strconv(f1,128),14,4),64) & space(4-lenb(midb(strconv(f1,128),14,4)))) from sample#txt

 と訂正してください。訂正後、接続ファイルのエクスポートをクリックして

 接続ファイル(sample#txt.odc)を上書き保存後、OKボタンクリックで

 「データインポート」ダイアログに戻りますから、データを表示させてみてください。

 一度作成してしまえば、既存の接続からこの接続ファイルは、どのブックからでも呼び出せます。

 以上です。

 ichinose


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.