VB6でNKF32.dllでEUCをSJISへ変換

解決


rtye  2006-02-02 10:42:12  No: 93932

NKF32.dllでEUCをSJISへ変換をしたいのですがいいサンプルが見付かりません。
ファイルを読み込んで変換するというのはありましたが、やりたいのは、EUCの文字列を渡して変換された文字列が帰ってくるような関数を探してます。


Blue  2006-02-02 12:08:22  No: 93933

ADODB.Streamを使うのはどうでしょうか?

EUC文字列をどのように保持しているかわからないので、仮に
String型だとすると↓の例のように変換できます。
例)
Private Sub test()
    Dim s As String ' Shift_JIS文字列
    
    With CreateObject("ADODB.Stream")
        .Open
        .Type = adTypeText
        ' ここでEUC文字列を指定する
        .WriteText "abc"
        .Position = 0
        .Charset = "shift_jis"
        ' Shift_JIS文字列を取得
        s = .ReadText
        .Close
    End With
End Sub

バイト型の配列で持っている場合は、TypeをadTypeBinaryにして
Writeメソッドで配列を書き込めばよいです。


Blue  2006-02-02 12:13:16  No: 93934

.Charset = "euc-jp"
が書き込む前に必要かも。

微妙なので、
http://madia.world.coocan.jp/cgi-bin/VBBBS/wwwlng.cgi?print+200405/04050030.txt
を参考にしてください。


Blue  2006-02-02 12:17:31  No: 93935

なんどもスイマセン。

> .Charset = "euc-jp"
> が書き込む前に必要かも。
じゃなくて、

>        .Charset = "shift_jis"
.Charset = "euc-jp" '書き込まれているテキストのコード
>        ' Shift_JIS文字列を取得
        ' Unicode文字列を取得(Shift_JISにはStrConvで)
>       s = .ReadText
ですね。

EUC文字列がString変数だとちょっと厄介かも。(未検証)


rtye  2006-02-02 14:33:17  No: 93936

ありがとうございます。

NKF32.dllを使わずにADOで処理しました。

ADOでうまく言ったかなと思ったのですが、いくつか文字化けをしているのがあります。すべてが文字化けではなくてその文字列中の何かが文字化けしてたりしてます。なぜでしょうか?

以下、コードです。

リンク中の魔界さんのコードを使わせていただきました。

Private Function ConvertEUCtoShiftJIS(ByVal Text As String) As String

    Dim adoStream As ADODB.Stream
    Dim i As Integer
    Dim intTextLen As Integer
    Dim bytTmpb()    As Byte
    Dim bytKeyBuff() As Byte

    intTextLen = LenB(StrConv(Text, vbFromUnicode))
    bytTmpb = StrConv(Text, vbFromUnicode)
    ReDim bytKeyBuff(1 To intTextLen) As Byte
    For i = 1 To intTextLen
        bytKeyBuff(i) = bytTmpb(i - 1)
    Next i

    Set adoStream = New ADODB.Stream
    With adoStream
        .Open
        .Type = adTypeBinary
        .Write bytKeyBuff
        .Position = 0
        .Type = adTypeText
        .Charset = "EUC-JP"
        ConvertEUCtoShiftJIS = .ReadText(adReadAll)
        .Close
    End With
    Set adoStream = Nothing

End Function


Blue  2006-02-02 15:09:45  No: 93937

>     bytTmpb = StrConv(Text, vbFromUnicode)
がダメそう。
Textってのが EUC 文字列なんでしょうか?
StrConv(Text, vbFromUnicode)

すると、TextはUnicode文字列としてShift_JISに変換するようになっています。

EUC文字列はどのようにして取得されているのでしょうか?


Blue  2006-02-02 15:18:30  No: 93938

もしかして、WinAPIで文字列を取得するときみたいに

Declare〜

として、文字列変数を引数に渡しているとかでしょうか?
そしたら String を変数にするのは大問題です。

たしか、StringでDLL等に渡すときに、文字コードが勝手に Unicode から Shift_JIS に変換するようになっています。
そして、DLLから帰ってくるときにまた、Shift_JISをUnicodeに戻します。

よって、DLL側で渡された String変数に直接 euc-jp の文字列を入れると問題があります。


rtye  2006-02-02 15:33:17  No: 93939

Debug.Print ConvertEUCtoShiftJIS("EUC文字列")
というふうに使用してます。
ConvertEUCtoShiftJISの引数の型(String)がだめってことですか?

>EUC文字列はどのようにして取得されているのでしょうか?
LINUXサーバのMySQLデータベースからODBC経由でリンクさせて取得しています。
ODBC経由で接続すると文字化けしてしまうので、VBのほうでEUCを変換仕様としています。
本当はODBCで文字化けせずにできたら一番いいのですが・・・
色々と調べてやってみましたがだめでした。なので後者のやり方でやろうとしています。


Blue  2006-02-02 16:04:02  No: 93940

とりあえず、
> ConvertEUCtoShiftJIS
という関数名は違っていますね。

>       .Charset = "EUC-JP"
>       ConvertEUCtoShiftJIS = .ReadText(adReadAll)
で EUC-JPコード の内容を Unicode文字列として取得するということなので、
取得できるのは Shift_JISコードではありません。(StrConvで変換しないといけない)
# というか、VBの内部ではUnicodeで持ったほうがよいのでは?

EUCコードのString変数をバイト型配列にできれば万事おっけなんですけどね。
MemoryCopy API とかつかえないかなぁ、、、(時間がなくて試せない)


rtye  2006-02-02 17:04:08  No: 93941

>とりあえず、
>> ConvertEUCtoShiftJIS
>いう関数名は違っていますね。
どういうことですか?

>EUCコードのString変数をバイト型配列にできれば万事おっけなんですけどね。
バイト型配列に格納してやってます。


Blue  2006-02-02 17:27:52  No: 93942

> どういうことですか?

> で EUC-JPコード の内容を Unicode文字列として取得するということなので、
> 取得できるのは Shift_JISコードではありません。(StrConvで変換しないといけない)
名前を付けるならば ConvertEUCtoUnicode でしょう。

> バイト型配列に格納してやってます。
正しいくバイト型配列ならば、そのままSaveAsメソッドで保存して、
テキストエディタで EUC コード として確認してみてください。
おかしな文字列ならば、バイト型配列変換に誤りがあることになります。


もげ  2006-02-02 17:34:07  No: 93943

>本当はODBCで文字化けせずにできたら一番いいのですが
の方面では、以下をどうぞ。
|Control パネルで `EUC 変換する’をチェックする事により、sjis←→ujis 変換を行います
とか記述がありますが、コレを試してもダメだったのでしょうか?
http://www.softagency.co.jp/products/mysql/win_myodbc.html
'純粋にVBの話でなくなるので、MySQLの掲示板等が適してるでしょう


Blue  2006-02-02 17:35:11  No: 93944

もしかして、バイト型配列にしなくても、Shift_JISで保存すれば

Private Function ConvertEUCtoUnicode(ByVal Text As String) As String
    With CreateObject("ADODB.Stream")
        .Open
        .Type = adTypeText
        .Charset = "shift-jis"
        .WriteText Text
        .Position = 0
        .Charset = "EUC-JP"
        ConvertEUCtoUnicode = .ReadText(adReadAll)
        .Close
    End With
End Function

でいけるかも。


魔界の仮面弁士  2006-02-03 01:15:58  No: 93945

> リンク中の魔界さんのコードを使わせていただきました。
そういう略し方は勘弁してください。
http://yaplog.jp/orator/archive/20


で。EUC → SJIS 変換との事ですが、元のEUCデータはどのようにして
得たものなのでしょうか? 変換前の時点でデータ化けしているようだと、
どうにもなりませんが、最初の入力が String というのは、聊か問題です。

既に他の方も書かれていますが、VB6 の String 型は、中身が UTF-16 で
ある事が期待されているため、ほかの文字コードのデータを突っ込むと、
文字列操作等の段階で、データが破損する可能性が出てしまいます。
StrConvなどは論外です。


文字列操作系の命令を使わなければ、データは破損しませんが、それにしても
この手の文字コード変換で、EUC String → SJIS String というのは、
あまり一般的では無いと思います。通常は、
  1) EUCファイル → Unicode String
  2) EUCファイル → Shift_JISバイナリ(Byte配列)
  3) EUCファイル → テキストストリーム(ADODB.Stream)
  4) EUCファイル → Shift_JISファイル
  5) EUCバイナリ → Unicode String
  6) EUCバイナリ → Shift_JISバイナリ(Byte配列)
  7) EUCバイナリ → テキストストリーム(ADODB.Stream)
  8) EUCバイナリ → Shift_JISファイル
などのように、入力は「ファイル」または「Byte配列」にしておきましょう。

(ADODB.Stream には、ファイルを直接読み取る為の命令もありますし)


たくみ  2006-02-03 09:22:33  No: 93946

横からすみません。

MyODBC3.51EUC変換版+VB6の環境、重宝しています。
MySQLの掲示板でないから手短に書きますね。。

もげさんの書かれた、
> コレを試してもダメだったのでしょうか?
http://www.softagency.co.jp/products/mysql/win_myodbc.html
に1票。

たぶんこれと同じことをしたいだけなんじゃないかと。。。
あ、ただしMySQLのバージョンとMyODBCとのバージョンの組み合わせ
にはご注意ください。

例えばMySQL4.0.2xではOKですが、MySQL4.1.x以降ではこのODBCはNGです。
逆に言うと、(MySQL4.1以降)だからこのスレの機能を
自作したいのかなあ?

ちなみに上記リンクと同様ですが、わかりやすく書かれた
http://allabout.co.jp/career/database/closeup/CU20021003/
もどうぞ。


rtye  2006-02-03 11:04:55  No: 93947

>コレを試してもダメだったのでしょうか?
>http://www.softagency.co.jp/products/mysql/win_myodbc.html
では文字化けせずできました。

ConnectionString  で実現できませんか?


たくみ  2006-02-03 11:33:28  No: 93948

> では文字化けせずできました。
ん?

> 本当はODBCで文字化けせずにできたら一番いいのですが・・・
> 色々と調べてやってみましたがだめでした。なので後者のやり方で
> やろうとしています。
だったんじゃ?

やりたいことの動機とどういう条件下などかが見えません。

魔界の仮面弁士さんも言われていますが
> 元のEUCデータはどのようにして
> 得たものなのでしょうか? 
にせめて答えて次の質問をされるべきではないでしょうか。

> ConnectionString  で実現できませんか?
もしかしてこのMyODBCを各クライアントPCにインストールしたくないとか
ODBC経由だとパフォーマンスが遅い云々でいやだなどという動機?

#そうなるともうこのスレの質問じゃないんじゃ。。


rtye  2006-02-03 15:12:19  No: 93949

>魔界の仮面弁士さんも言われていますが
>> 元のEUCデータはどのようにして
>> 得たものなのでしょうか? 
>にせめて答えて次の質問をされるべきではないでしょうか。
ちゃんと書いてますが・・・・

>もしかしてこのMyODBCを各クライアントPCにインストールしたくないとか
>ODBC経由だとパフォーマンスが遅い云々でいやだなどという動機?
はい、そうです。
現在はMyODBCをインストールしてDSNを作成してそれをADOで使用しています。
MyODBCは各クライアントにインストールしますが、DSNを作成せずにADOで接続がしたいのです。
ADOのConnectionStringで'OPTION=16387'みたいに「EUCに変換」のオプションをつけるようにして接続がしたいのですが出来ません。

スレッドが長くなりましたので、新しいスレッドを立てますのでそちらへお願いします。


※作成する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。







   このエントリーをはてなブックマークに追加