Access VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


126 / 2272 ツリー ←次へ | 前へ→

【12918】指定文字数にしたい あおぎん 16/1/8(金) 12:06 質問[未読]
【12919】Re:指定文字数にしたい かるびの 16/1/8(金) 15:59 回答[未読]
【12920】Re:指定文字数にしたい あおぎん 16/1/14(木) 10:45 質問[未読]
【12921】Re:指定文字数にしたい かるびの 16/1/14(木) 11:57 回答[未読]
【12922】Re:指定文字数にしたい あおぎん 16/1/14(木) 16:16 お礼[未読]
【12926】Re:指定文字数にしたい かるびの 16/1/16(土) 16:34 発言[未読]
【12933】Re:指定文字数にしたい あおぎん 16/2/4(木) 19:01 お礼[未読]

【12918】指定文字数にしたい
質問  あおぎん  - 16/1/8(金) 12:06 -

引用なし
パスワード
   いつも参考にさせていただいています。

CSV出力用ファイルをアクセスで作成しているのですが、文字数指定で苦労しています。

64バイトと指定のある「名称」という項目があり、入力データは全角文字で8文字から20文字程度とまちまちなため

クエリで 名称変換:LeftB$([名称] & Space$(64),64)とし、64バイト分抽出しているのですが、

表示させてみると文字の長さがまちまちのようなのです。
名称変換の桁数を調べるとすべて32となっておりどうも全角文字数+半角スペースの数=32とはなっているようですが・・(全角文字10+半角スペース22とか全角文字12+半角スペース10とかになっています。)

クエリが間違っていますでしょうか??
ヒントでもよいのでご教示いただけると幸いです。
どうぞよろしくお願いいたします。


アクセス2007 Win2007

【12919】Re:指定文字数にしたい
回答  かるびの  - 16/1/8(金) 15:59 -

引用なし
パスワード
    アクセス2007では、文字コードはUnicodeが使われていたと思いますが、
Unicodeでは半角文字も2バイトとなります。
 だから、全角半角文字混在の場合、文字列の終了位置は全角半角の混在具合によって変わってきます。


 例えば、20バイトの文字列をいくつか掲げてみます。

あいうえおかきくけこ
あいうえお12345
あいう1234567
あ123456789

となります。


 なので、
>表示させてみると文字の長さがまちまちのようなのです。
でいう「文字の長さ」というのが上記で示した文字列の終了位置のことを言っているのであれば、
Unicodeを使う以上、文字列の終了位置がまちまちになるのは
当然のことだと思います。


 なお、文字コードがShift-JISであれば、全角2バイト、半角1バイト
となりますから、
64バイトの文字列の文字数は、Unicodeの場合とは変わってきます。


 ところで、出力用のCSVファイルの文字コードはUnicodeでいいんでしょうか。

【12920】Re:指定文字数にしたい
質問  あおぎん  - 16/1/14(木) 10:45 -

引用なし
パスワード
   ▼かるびの さん:

レスポンスが遅くなって申し訳ありません。
回答ありがとうございます。半角は1バイトだと思い込んでおりました。
文字列の終了位置がまちまちな理由が理解できました。ありがとうございます。

>
> ところで、出力用のCSVファイルの文字コードはUnicodeでいいんでしょうか。

シフトJISコードで作成する仕様となっています。
エクスポート定義でシフトJISを指定しているので、CSVはシフトJISで作成されているんだと思います。


足すスペースを半角から全角スペースにして64バイト抜き出したらいいかと思いましたが、全角スペースを置く関数がよくわからなかったので、クエリの & Space$(64)を、& "〜32文字分の全角スペース〜 "に変更したら、終了位置は揃ったのですが、なにぶん知識が薄いので、、、これでいいんでしょうか?

間違ってたり、もっとスマートな?やり方などあればご教示いただけると助かります。
よろしくお願いいたします。

【12921】Re:指定文字数にしたい
回答  かるびの  - 16/1/14(木) 11:57 -

引用なし
パスワード
   >クエリの & Space$(64)を、& "〜32文字分の全角
>スペース〜 "に変更したら、終了位置は揃ったのですが、なにぶん知識が薄いので、、、これで
>いいんでしょうか?

 それでいいと思います。

 ほかにも方法が考えられますが、その方法がベストだと思います。


 ほかに考えられる方法について触れておきます。

 まず、32文字分の全角スペースを作る方法です。
 これについては、String 関数という関数が使えます。
 String 関数を使えば、クエリの演算フィールドに設定する式を短くすることができます。
 反面、関数呼出を伴うため、その分だけクエリが遅くなります。
もっとも、人間には気付かないくらいの差だとは思いますが。


 次に、64バイトの文字列を作るに当たり、
追加する全角スペースの数をその都度調整するという方法が考えられます。

 具体的には、
64バイトから、「名称」の文字列のバイト数を引き、
これを2で割って、追加する全角スペースの文字数を求め、
その分だけ、全角スペースを追加する
という方法です。

 しかし、いくつかの関数呼出を必要とするので、その分遅くなります(でも、きっと、気付かないくらいの差)。
 また、式が長くなりそうです。
 さらに、「名称」に半角文字が含まれていた場合、
出来上がる文字列が63バイトとか、65バイトになったりする
ということもあり得そうです。

 
 こうしたことを考えると、あおぎんさんの方法がベストかなと思います。

【12922】Re:指定文字数にしたい
お礼  あおぎん  - 16/1/14(木) 16:16 -

引用なし
パスワード
   ▼かるびの さん:

さっそくお返事ありがとうございます。

>>クエリの & Space$(64)を、& "〜32文字分の全角
>>スペース〜 "に変更したら、終了位置は揃ったのですが、なにぶん知識が薄いので、、、これで
>>いいんでしょうか?
>
> それでいいと思います。
> ほかにも方法が考えられますが、その方法がベストだと思います。

安心しました^^

それから、他の方法も教えていただきありがとうございます。
String 関数を調べて使ってみたら同じ結果になりました!
見た目スマートなのでこちらに変えようと思います^^

> さらに、「名称」に半角文字が含まれていた場合、
>出来上がる文字列が63バイトとか、65バイトになったりする
>ということもあり得そうです。

今のところ名称は全角を使うこととしているため、問題ないのですが、ためしに半角1文字を混ぜてみたら、おっしゃるとおり、シフトJISだと63バイトになってしまいました。

今回は半角文字の対応はしなくても大丈夫そうなのですが、これをきちんと出す方法があれば、後学のために教えていただけるとうれしいです。

ない頭を振り絞って考えると、例えば文字列に含まれる半角の数によって、半角スペースを足して、抽出するバイト数を変更するなどすれば・・などと思いますが、半角の数のカウントって簡単にはできないみたいですね;


面倒であればスルーしてください!
回答ありがとうございました!助かりました。

【12926】Re:指定文字数にしたい
発言  かるびの  - 16/1/16(土) 16:34 -

引用なし
パスワード
   >今回は半角文字の対応はしなくても大丈夫そうなのですが、これをきちんと出す方法があれば、
>後学のために教えていただけるとうれしいです。

 これへの対応方法について興味が湧いたので、その対応方法を考えてみました。

 細かな処理を要するので、関数化します。

Function FnGetStr(ByVal strUni As String _
        , lngJisLen As Long _
        , strAddFull As String _
        , strAddHalf As String) As String
'UnicodeのstrUni文字列から、Shift-Jisで数えてlngJisLen分のバイト数の文字列を切り出す関数
'引数 strUni 文字列の切り出し元となるUnicodeの文字列)
'   lngJisLen 切り出すバイト数(Shift-Jisで計算)
'   strAddFull strUniがlngJisLenより短い場合に付加する全角の文字
'    strAddHalf strUniのバイト数が奇数になる場合に付加する半角の文字
'返り値 UnicodeのstrUni文字列から、Shift-Jisで数えてlngJisLen分のバイト数分を取り出した文字列(Unicode)
  
  Dim i As Long
  Dim strJis(1) As String  '添え字:0=前回ループ、1=今回ループ    
  Dim lngLen As Long
  Dim strRslt As String
  Dim strDbgUni As String  'デバッグ用
  
  'strUniがlngJisLenよりも短い場合に備えて、全角文字を付加
  strUni = strUni & String(lngJisLen, strAddFull)
  
  'Shift-JisによるstrUniのバイト数を調査。
  For i = Int(lngJisLen / 2) To Len(strUni)
    strJis(1) = Left(strUni, i)
    strJis(1) = StrConv(strJis(1), vbFromUnicode)
    
    If (LenB(strJis(1)) > lngJisLen) Then
      Exit For
    End If
    
    strJis(0) = strJis(1)
    
    strDbgUni = StrConv(strJis(0), vbUnicode) 'デバッグ用
  Next i

  'strUniから該当部分を切り出す。
  strRslt = Left(strUni, i - 1)
  lngLen = LenB(strJis(0))

  'Shift-Jisのバイト数が奇数になってしまう場合に備えて、半角文字を追加
  If lngJisLen - lngLen = 1 Then
    strRslt = strRslt & strAddHalf
  End If
  
  FnGetStr = strRslt
End Function

【12933】Re:指定文字数にしたい
お礼  あおぎん  - 16/2/4(木) 19:01 -

引用なし
パスワード
   ▼かるびの さん:

対応方法を教えていただいてありがとうございます。
すっかりお返事遅くなりまして申し訳ないです。

実際やってみてからと思っていたんですが、どうもうまくいかず。。

CSV作成用データベースで動かすとコンパイルエラーとなってしまいます。

あきらめてまっさらのデータベースでやってみるとうまくいきました!
CSV作成用のデータベースだとなぜできないのだろう??

何はともあれありがとうございました!

126 / 2272 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
1078188
(SS)C-BOARD v3.8 is Free