tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトル区点コードからの文字入力
記事No10578
投稿日: 2011/09/07(Wed) 18:46
投稿者よっくん
こんにちは。

----環境----
Windows XP SP3
VB2005
IME 2003
------------

件名通りなのですが、
テキストボックス1に区点コードを入力

テキストボックス2に対応した漢字を表示

というプログラムを作りたいのですが、
区点コードから漢字を取得する方法を
ご存じの方、教えて頂けないでしょうか。

該当PCには外字がたくさん登録されており、
よく使う文字は区点コードを控えているので
区点コードから入力できれば… と思っております。

宜しくお願い致します。

[ツリー表示へ]
タイトルRe: 区点コードからの文字入力
記事No10579
投稿日: 2011/09/07(Wed) 20:13
投稿者YuO
> 件名通りなのですが、
> テキストボックス1に区点コードを入力
> ↓
> テキストボックス2に対応した漢字を表示
> というプログラムを作りたいのですが、
> 区点コードから漢字を取得する方法を
> ご存じの方、教えて頂けないでしょうか。

直接的な方法はないですが,
・ISO-2022-JPのG0をJIS X 0208に選択するエスケープバイト列,区点コードの両バイトに&H20をそれぞれ足した値,を並べたバイト列をEncoding.GetEncoding("ISO-2022-JP").GetStringに渡す
・両バイトに&HA0足してEUC-JPのG1扱いにしてEncoding.GetEncoding("EUC-JP").GetStringに渡す
あたりが思いつきます。

が……

> 該当PCには外字がたくさん登録されており、
> よく使う文字は区点コードを控えているので
> 区点コードから入力できれば… と思っております。

95区以上はJIS X 0208 (94 x 94) の範囲外であるため,この範囲のPUAを表すにはShift_JIS扱いになるよう計算して変換しないといけません。
PUAはISO-2022-JP/EUC-JPで表せない範囲まであるので,一番の解決策はPUA領域の文字はUnicodeで文字コードを記録しておくことだと思います。
# PUA : Private Use Area

[ツリー表示へ]
タイトルRe^2: 区点コードからの文字入力
記事No10581
投稿日: 2011/09/07(Wed) 21:05
投稿者魔界の仮面弁士
> ・両バイトに&HA0足してEUC-JPのG1扱いにしてEncoding.GetEncoding("EUC-JP").GetStringに渡す

Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
    Dim 区点 As Integer
    If Integer.TryParse(TextBox1.Text, 区点) Then
        Dim 区番号 As Byte = CByte((区点 \ 100) And &HFF)
        Dim 点番号 As Byte = CByte(区点 Mod 100)
        Dim euc() As Byte = {CByte((区点 \ 100) + &HA0), CByte((区点 Mod 100) + &HA0)}
        TextBox2.Text = System.Text.Encoding.GetEncoding("euc-jp").GetString(euc)
    Else
        TextBox2.Clear()
    End If
End Sub

[ツリー表示へ]
タイトルRe^3: 区点コードからの文字入力
記事No10582
投稿日: 2011/09/08(Thu) 10:57
投稿者よっくん
YuO様 魔界の仮面弁士様
アドバイスありがとうございます。

YuO様
>95区以上はJIS X 0208 (94 x 94) の範囲外であるため,この範囲のPUAを表すにはShift_JIS扱いになるよう計算して変換しないといけません。

まさにこの壁にぶち当たっております…。
実際に入力で使う値は
区点コード 09501〜11494  になります。(後出し情報でスミマセン)
(Shift JIS:0xF040〜0xF9FC)
(Unicode:U+E000〜U+E757)

最初、区点コードから表示したい文字のShift JISのコードをIMEパッドで調べて(目で視て)
SJIS値から-65536した値でChr関数で出るじゃん!と思っていたのですが
区点コード→Shift JISコードへの変換がうまく出来ず(そもそも可能なのかどうか判って無いのですが)
直接区点コードから文字が求められれば… と思っておりました。

>PUAはISO-2022-JP/EUC-JPで表せない範囲まであるので,一番の解決策はPUA領域の文字はUnicodeで文字コードを記録しておくことだと思います。

う〜ん、控える文字を間違えてましたね…orz


魔界の仮面弁士様
サンプルコード ありがとうございます。
94区までは表示されましたが、95区は表示できませんでした。
入力区点コードは09501〜11494になります。(後出し情報でスミマセン)

文字コードって奥が深いですね…orz

[ツリー表示へ]
タイトルRe^4: 【ぷち解決】区点コードからの文字入力
記事No10583
投稿日: 2011/09/08(Thu) 19:17
投稿者よっくん
完全ではありませんが
とりあえず出来るようになったので
コードを記載しておきます。
(殴り書きレベルですが…)
結局、
区点コード→JISコード→SHIFT_JISコードに変換して
出てきたSHIFT_JISコード - 65536 の値でChr関数を実行
という処理になっています。
JISコード→SHIFT_JISコード変換は
以下のサイトの末尾の方を参考にしました。
http://www.unixuser.org/~euske/doc/kanjicode/index.html

        Dim JISC As Long
        Dim JISC_Str As String 'JISコード文字列

        Dim Bit2 As String
        Dim Bit1 As String

        Dim Joui As String
        Dim Kai As String

        Try

            If e.KeyChar = ChrW(Keys.Enter) Then

                '区点コード→JISコード変換
                Dim KCODE As String = CLng(Me.txt_区点.Text).ToString("00000")


                JISC = CLng(Mid(KCODE, 1, 3)) + 32
                JISC = JISC * 256
                JISC = JISC + CLng(Mid(KCODE, 4, 2)) + 32
                JISC_Str = Hex(JISC).ToString


                'JISコード→SJISコード変換

                '上位2文字下位2文字に分ける
                Joui = Mid(JISC_Str, 1, 2)
                Kai = Mid(JISC_Str, 3, 2)

                '上位2文字処理

                '21H引く(10進で33)
                Joui = Hex(CLng("&H" & Joui) - 33).ToString

                '2進数変換(16進→2進)
                Bit2 = Convert.ToString(Convert.ToInt32(Joui, 16), 2)
                Bit2 = CDbl(Bit2).ToString("00000000") '桁揃え

                '下1桁キープ→下位2文字処理時に使う
                Bit1 = Mid(Bit2, 8, 1)

                '上位7桁だけ取り出し
                Bit2 = Mid(Bit2, 1, 7)

                '上位7桁を16進にして格納(2進→16進)
                Joui = Convert.ToInt32(Bit2, 2).ToString("X")


                Select Case CLng("&H" & Joui)
                    Case 0 To 30
                        '+81H する(10進で129
                        Joui = Hex(CLng("&H" & Joui) + 129).ToString

                    Case Else
                        '+C1H する(10進で193
                        Joui = Hex(CLng("&H" & Joui) + 193).ToString

                End Select
                'この時点で上位2文字確定


                '下位処理
                '上位処理時の下位1ビットで処理が変わる
                If Bit1 = "0" Then
                    '+1FHする(10進で31
                    Kai = Hex(CLng("&H" & Kai) + 31).ToString

                    Select Case CLng("&H" & Kai)
                        Case 64 To 126
                            'そのまま

                        Case Else
                            '+1Hする(10進で1
                            Kai = Hex(CLng("&H" & Kai) + 1).ToString

                    End Select

                Else
                    '+7EHする(10進で126
                    Kai = Hex(CLng("&H" & Kai) + 126).ToString

                End If
                'この時点で下位確定

                Me.txt_Kekka.Text = Chr(CLng("&H" & Joui & Kai) - 65536)

            End If

        Catch ex As Exception
            Me.txt_Kekka.Text = "Error"
        End Try


※注意
・入力値 区点コードは 9501〜11494の間しか試してません
・全部の文字を目視確認した訳では無いので 100% OKとは言えません
・以下の区点コードが入力されたらコケます
9698 9699 9898 9899 10098 10099 10298 10299 10498 10499 10698
10699 10898 10899 11098 11099 11298 11299

[ツリー表示へ]
タイトルRe^5: 【ぷち解決】区点コードからの文字入力
記事No10584
投稿日: 2011/09/12(Mon) 18:39
投稿者魔界の仮面弁士
> Dim JISC As Long
> Dim KCODE As String = CLng(Me.txt_区点.Text).ToString("00000")
本当に Long 型が必要でしょうか。
 ULong   の最大値は「18,446,744,073,709,551,615」
 Long    の最大値は「9,223,372,036,854,775,807」
 UIntegerの最大値は「4,294,967,295」
 Integer の最大値は「2,147,483,647」
 UShort  の最大値は「65,535」
 Short   の最大値は「32,767」
なので、Long では大袈裟すぎるように思います。


> ・以下の区点コードが入力されたらコケます
> 9698 9699 9898 9899 10098 10099 10298 10299 10498 10499 10698
> 10699 10898 10899 11098 11099 11298 11299
上記はいずれも点番号が 98〜99 なので、エラーとして扱って良いと思いますよ。

Shift_JIS (SJIS) がとりうる範囲は「区番号=1〜94、点番号=1〜94」ですし、
Windows-31J (CP932) だとしても「区番号=1〜120、点番号=1〜94」ですから。

[ツリー表示へ]