Excel VBA質問箱 IV

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

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


3917 / 13644 ツリー ←次へ | 前へ→

【59487】EUC→Unicodeのコード変換 おさっち 08/12/13(土) 1:40 質問[未読]
【59488】Re:EUC→Unicodeのコード変換 おさっち 08/12/13(土) 8:45 発言[未読]
【59489】Re:EUC→Unicodeのコード変換 neptune 08/12/13(土) 9:49 発言[未読]
【59493】Re:EUC→Unicodeのコード変換 おさっち 08/12/13(土) 12:04 質問[未読]
【59494】Re:EUC→Unicodeのコード変換 おさっち 08/12/13(土) 17:30 発言[未読]
【59496】Re:EUC→Unicodeのコード変換 neptune 08/12/13(土) 20:18 発言[未読]
【59498】Re:EUC→Unicodeのコード変換 おさっち 08/12/13(土) 20:39 発言[未読]
【59500】Re:EUC→Unicodeのコード変換 neptune 08/12/13(土) 21:17 発言[未読]
【59501】Re:EUC→Unicodeのコード変換 neptune 08/12/13(土) 21:44 発言[未読]
【59503】Re:EUC→Unicodeのコード変換 kazuyoshikakihara 08/12/14(日) 10:34 回答[未読]
【59505】Re:EUC→Unicodeのコード変換 おさっち 08/12/14(日) 16:27 お礼[未読]

【59487】EUC→Unicodeのコード変換
質問  おさっち  - 08/12/13(土) 1:40 -

引用なし
パスワード
   「おさっち」と申します。
どうぞよろしくお願いいたします。

Excel2003のVBAマクロで、ODBCを経由でSQLite3のデータベースをアクセスしようとしています。
データベースには、EUCでエンコードされたデータが入っています。
Excelは文字データをUnicodeで管理しているので、そのままセルに書き込んだら文字化けしてしまいます、
EUC→Unicodeのコード変換が必要だということはわかったのですが、具体的な方法がわかりません。

とりあえずは、読むだけの以下のようなマクロを組んでいるのですが、文字化けしています。
どのようにすれば、文字化けを解消できるでしょうか?

文字化けせず読むことができたら、Unicode→EUCのコード変換を行った追加・更新もしたいと考えています。
こちらもよろしくお願いいたします。


Public Sub For_Question()

Dim cnDatabase As ADODB.Connection
Dim rs As New ADODB.Recordset
Dim m_Field As ADODB.Field

Dim i As Long, j As Long

Dim Sql As String
Dim cnt As String
 
cnt = "Driver=SQLite3 ODBC Driver; Database=C:\excel_sqlite3_test\test.db"
Set cnDatabase = New ADODB.Connection

cnDatabase.Open cnt

Worksheets("methodtbl").Select
Cells.Select
Selection.Clear
Cells(1, 1).Select

Sql = "SELECT * FROM methodtbl"

rs.Open Sql, cnDatabase, adOpenForwardOnly

'フィールド名表示
j = 1
For Each m_Field In rs.Fields

    Cells(1, j).Value = m_Field.Name
    
    j = j + 1
Next m_Field


'データ表示
i = 2

Do Until rs.EOF
 
  j = 1

  For Each m_Field In rs.Fields
 
    Cells(i, j).Select
    Cells(i, j).Value = "'" & m_Field.Value
      
    j = j + 1

  Next m_Field
 
  i = i + 1
 
  rs.MoveNext
Loop
  
  
rs.Close
Set rs = Nothing


End Sub

【59488】Re:EUC→Unicodeのコード変換
発言  おさっち  - 08/12/13(土) 8:45 -

引用なし
パスワード
   「おさっち」です。

前の質問で書き忘れていたことがありますので、追記します。

・試してみたこと
民芸的プログラミング 〜ソフトウェア開発日記〜
「SQLiteの面白さ(23) ODBCドライバをさらに改造した」
kzworks.at.webry.info/200807/article_4.html
で紹介されているODBCドライバで上書きし、コンピュータをリブートしました。

以上です。

よろしくお願いします。

【59489】Re:EUC→Unicodeのコード変換
発言  neptune  - 08/12/13(土) 9:49 -

引用なし
パスワード
   ▼おさっち さん:
こんにちは

DBでやった事はないのですが、ADOのStream オブジェクトを調べてください。
Excelへの取り込みはrecordsetからstreamを開きCharset プロパティを設定する
ことで何とかできると思います。

出来たら教えてくださいね。

【59493】Re:EUC→Unicodeのコード変換
質問  おさっち  - 08/12/13(土) 12:04 -

引用なし
パスワード
   ▼neptune さん:
どうもありがとうございます。

以下のようにプログラムを変更してみました。

-------------------------------------------------------

Public Sub For_Question2()

Dim cnDatabase As ADODB.Connection
Dim rs As New ADODB.Recordset
Dim in_strm As ADODB.Stream
Dim out_strm As ADODB.Stream
Dim m_Field As ADODB.Field

Dim i As Long, j As Long

Dim Sql As String
Dim cnt As String

Dim m_string As String, m_byte1() As Byte, m_byte2() As Byte

 
cnt = "Driver=SQLite3 ODBC Driver; Database=C:\excel_sqlite3_test\test.db"
Set cnDatabase = New ADODB.Connection

cnDatabase.Open cnt

Worksheets("methodtbl").Select
Cells.Select
Selection.Clear
Cells(1, 1).Select

Sql = "SELECT * FROM methodtbl"

rs.Open Sql, cnDatabase, adOpenForwardOnly

'フィールド名表示
j = 1
For Each m_Field In rs.Fields

    Cells(1, j).Value = m_Field.Name
    
    j = j + 1
Next m_Field


'データ表示
i = 2

Do Until rs.EOF
 
  j = 1

  For Each m_Field In rs.Fields

    Cells(i, j).Select
    'Cells(i, j).Value = "'" & m_Field.Value
   
    Set in_strm = New ADODB.Stream
    Set out_strm = New ADODB.Stream
   
    in_strm.Open
    out_strm.Open
   
    in_strm.Charset = "EUC-JP"
    in_strm.Type = adTypeBinary
    out_strm.Charset = "SJIS"
    out_strm.Type = adTypeBinary
       
    m_byte1() = m_Field.Value
    in_strm.Write m_byte1
    in_strm.CopyTo out_strm
    out_strm.Read m_byte2
   
    in_strm.Close
    out_strm.Close
   
    Set in_strm = Nothing
    Set out_strm = Nothing
   
    Cells(i, j).Value = CStr(m_byte2)
      
    j = j + 1

  Next m_Field
 
  i = i + 1
 
  rs.MoveNext
Loop
  
  
rs.Close
Set rs = Nothing


End Sub

-------------------------------------------------------


そうすると、
>out_strm.Read m_byte2
のところで実行時にエラーがでます。

-------------------------------------------------------

実行時エラー'3001':

引数が間違った型、許容範囲外、または競合しています。

-------------------------------------------------------

googleでいろいろ検索してみたのですが、原因がわかりません。
どこが間違っているのでしょうか?


どうぞよろしくお願いいたします。

【59494】Re:EUC→Unicodeのコード変換
発言  おさっち  - 08/12/13(土) 17:30 -

引用なし
パスワード
   「おさっち」です。

googleで、色々検索しました。

エラーの原因はわかりました。

>out_strm.Read m_byte2

「Read」の使い方が、やはり間違っていたようです。

>m_string2 = in_strm.Read(adReadAll)

とすれば、エラーはでなくなりました。

また、Charsetを有効になるのは、Type = adTypeTextのときだけで、
Type = adTypeTextではだめなようです。


それから、Charset = "SJIS" ではなく、Charset = "Shift_JIS"と書いてあるサイトもありました。

実際のデータベースでは、特定の列のみにEUCの文字が入っているので、そこだけを変換するように考えました。

以上を踏まえて、以下のように変更してみました。


-------------------------------------------------------------

Do Until rs.EOF
 
 j = 1

 For Each m_Field In rs.Fields

  Cells(i, j).Select
   
  If m_Field.Name = "t1" Then
  
    Set in_strm = CreateObject("ADODB.Stream")
    Set out_strm = CreateObject("ADODB.Stream")
      
    in_strm.Charset = "EUC-JP"
    in_strm.Type = adTypeText
   
    out_strm.Charset = "Shift_JIS"
    out_strm.Type = adTypeText
   
    in_strm.Open
    out_strm.Open
                   
    m_byte1 = m_Field.Value
    in_strm.WriteText m_byte1
    in_strm.Position = 0
   
    in_strm.CopyTo out_strm
   
    out_strm.Position = 0
          
    m_string2 = out_strm.ReadText(adReadAll)

    Cells(i, j).Value = m_string2
   
    in_strm.Close
    out_strm.Close
   
    Set in_strm = Nothing
    Set out_strm = Nothing
   
   
   Else
    Cells(i, j).Value = m_Field.Value
   End If   
 
   j = j + 1

  Next m_Field
 
  i = i + 1
 
  rs.MoveNext
Loop

-------------------------------------------------------------

これで、実行時エラーはでなくなりましたが、依然として文字化けはなおりません。

なお、データベースの内容は、EUC形式でダンプして、正常に文字が表示されたので、EUC形式であることは間違いないと思います。

アドバイス、よろしくお願いいたします。

【59496】Re:EUC→Unicodeのコード変換
発言  neptune  - 08/12/13(土) 20:18 -

引用なし
パスワード
   ▼おさっち さん:
こんにちは

昼間チラッと見て、時間が無かったので今もう一度見たら、
私にわかるところは既にご自分で見つけてました^ ^;;
(Shift_JISとTypeの件)

私も、recordsetからstreamを使用したこと長いので勉強になります。

ただ、EUCのDBの環境が無いので、調べきれないかもしれませんが、
私も調べてみます。

【59498】Re:EUC→Unicodeのコード変換
発言  おさっち  - 08/12/13(土) 20:39 -

引用なし
パスワード
   ▼neptune さん

どうもありがとうございます。

問題のDBですが、下記にアップロードさせていただいておりますので、よろしくお願いします。

www.bestlife-japan.net/sqlitetest/test.db

(たった3KBのDBです。)

【59500】Re:EUC→Unicodeのコード変換
発言  neptune  - 08/12/13(土) 21:17 -

引用なし
パスワード
   ▼おさっち さん:
こんにちは
MSDN見ながらテストコード書いてみました。
recordset取得後ちょっと入れてみて下さい。

'多分1行だけ表示(未テスト)
Public Sub ShowDatas(ByRef pRs As ADODB.Recordset)
  Dim stm As ADODB.Stream
  Dim rc As ADODB.Record
  Dim sBuf As String
  
  Set rc = New ADODB.Record
  'カレントレコードを取得
  rc.Open pRs
  
  Set stm = New ADODB.Stream
  With stm
    .Charset = "EUC-JP"
    .Type = adTypeText
    .Open rc, adModeRead, adOpenStreamFromRecord
    .ReadText
  End With
  Debug.Print sBuf
  
  stm.Close
  Set stm = Nothing
  rc.Close
  Set rc = Nothing
End Sub

【59501】Re:EUC→Unicodeのコード変換
発言  neptune  - 08/12/13(土) 21:44 -

引用なし
パスワード
   ▼おさっち さん:

SQLiteというのを忘れてました。

>問題のDBですが、下記にアップロードさせていただいておりますので、よろしくお願いします。
すみませんSQLiteをインストールしておりませんし、インストールする
つもりもありませんので、申し訳ないですが、やっぱり検証はできません。

【59503】Re:EUC→Unicodeのコード変換
回答  kazuyoshikakihara  - 08/12/14(日) 10:34 -

引用なし
パスワード
    SQLite3 用の ODBC ドライバの日本語対応をした者です。

 まず、SQLite3 に関してですが、SQLite3 では文字コードについては、Unicode での運用が原則になります(SQLite3 のホームページを参照してください)。
 SQLite3 は厳密には文字コードのチェックはしていませんので、Shift_JIS のデータでも、EUC のデータでも突っ込むことができますが、選択や並べ替えの際に不都合が生じるかも知れません。

 次に、SQLite3 用の ODBC ドライバ(日本語対応版)ですが、これは SQLite3 のテキストデータが、Unicode(UTF-8)であることを前提に、それを取り出す際に、SJIS に文字コードを変換するようになっています。
 ですので、おさっちさんのデータのように、中身が EUC になっていると正常に文字コードの変換が行えません。

 何か理由があって、元のデータが EUC になっているのでしょうが、SQLite3 が EUC に対応していない以上、このままデータを加工するのは別のトラブルの原因にもなりかねませんので、あまりお薦めできません。
 私でしたら、元のデータを一度 CSV 形式でテキストデータに書き出して、iconv などのツールで文字コードを UTF-8 に変換した上で、別の新しい SQLite3 のデータベースに読み込み、そちらのデータベースに ODBC 接続するというような運用を考えます。

【59505】Re:EUC→Unicodeのコード変換
お礼  おさっち  - 08/12/14(日) 16:27 -

引用なし
パスワード
   ▼kazuyoshikakihara さん

どうもありがとうございます。


> まず、SQLite3 に関してですが、SQLite3 では文字コードについては、Unicode での運用が原則になります(SQLite3 のホームページを参照してください)。
これは知りませんでした。
SQLite3のホームページを確認すると、「SQLite Version 3 Overview」のページに、「Support for both UTF-8 and UTF-16 text. 」と書かれています。

> 何か理由があって、元のデータが EUC になっているのでしょうが、SQLite3 が EUC に対応していない以上、このままデータを加工するのは別のトラブルの原因にもなりかねませんので、あまりお薦めできません。
あるベンダーのアプリケーションが作成・管理しているデータベースなので、なぜEUCなのかは私にもわかりません。

> 私でしたら、元のデータを一度 CSV 形式でテキストデータに書き出して、iconv などのツールで文字コードを UTF-8 に変換した上で、別の新しい SQLite3 のデータベースに読み込み、そちらのデータベースに ODBC 接続するというような運用を考えます。
ご助言ありがとうございます。
その方向で考えたいと思います。


neptune さんにも、色々調べていただき、感謝いたします。

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