見出し画像

Re:SALOON & VBA

EXCEL VBA 文字コード表作成

文字コード一覧表を作成するマクロを作成してみました。

次、入れるかも知れないお仕事で、
UTF-16を使うとのことなので・・・

**************************************************
Option Explicit

Sub MojiCodeTbl()
 Dim i   As Long  ' 行
 Dim k   As Long  ' 区
 Dim t   As Long  ' 点
 Dim jisCd As String ' JISコード
 Dim SjisCd As String ' Shift-JISコード
 Dim uniCd As String ' Unicode
 Dim Moji  As String ' 文字
 
 On Error Resume Next
 i = 1
 For k = 1 To 94
  For t = 1 To 94
  ' 区点 ==> JIS(16進数)
   jisCd = CStr(Hex(k + 32)) & CStr(Hex(t + 32))
  ' JIS(16進数) ==> S-JIS(16進数)
   SjisCd = Jis2SJis(jisCd)
  ' S-JIS(16進数) ==> 文字
   Moji = Chr(Int("&H" & SjisCd))
  ' 文字 ==> UTF16(16進数)
   uniCd = Right("00" & Hex(AscW(Moji)), 4)
   If uniCd = "30FB" And jisCd > "2126" Then
  '  Cells(i, 5).Value = "----"
   Else
    i = i + 1
    Cells(i, 1).Value = k   '区
    Cells(i, 2).Value = t   '点
    Cells(i, 3).Value = jisCd 'JIS
    Cells(i, 4).Value = SjisCd 'S-JIS
    Cells(i, 5).Value = uniCd 'UTF16
    Cells(i, 6).Value = Moji  '文字
    Cells(i, 6).Select
    If i = Int(i / 25) * 25 Then
     Application.ScreenUpdating = True
     Cells(i, 6).Select
     Application.ScreenUpdating = False
    End If
   End If
  Next t
 Next k
 Range(Cells(1, 1), Cells(i, 6)).Select
 Selection.Borders.LineStyle = xlContinuous
 Cells(1, 1).Select
 Application.ScreenUpdating = True
 Cells(2, 1).Select
End Sub

Function Jis2SJis(jis As String) As String
 Dim hi As Long
 Dim lo As Long
 hi = "&H" & Left(jis, 2)
 lo = "&H" & Right(jis, 2)
 If hi And 1 Then
  If lo < &H60 Then
   lo = lo + &H1F
  Else
   lo = lo + &H20
  End If
 Else
  lo = lo + &H7E
 End If
 If hi < &H5F Then
  hi = (hi + &HE1) \ 2
 Else
  hi = (hi + &H161) \ 2
 End If
 Jis2SJis = CStr(Hex(hi * &H100 + lo))
End Function

コメント一覧

⇒画像
修正③ JISコード一覧の形式変更
http://blogimg.goo.ne.jp/user_image/16/93/5c90613bdca568691494a5063be9da14.jpg
↑前回の、課題の解決案の改良版の追加です。
前回の処理の結果を、更に16列の折り返し表示に↓
http://blogimg.goo.ne.jp/user_image/16/93/5c90613bdca568691494a5063be9da14.jpg

シートコピーする処理を作成しました。

入力は、あくまで課題の解決案のシートなので、
縦一列の結果ありきの処理です。

暇が続くようなら、タウンロードから一括も・・・
作らないではないが・・・
(今は、出来て安堵、疲れているのでやらない)

************************************************************
Option Explicit

Sub UpMapCopy()
 Dim i As Long ' 元・行
 Dim j As Long ' 先・行(区第1行)
 Dim m As Long ' 面
 Dim k As Long ' 区
 Dim t As Long ' 点
 Dim n As Long ' 先・列
 Dim p As Long ' 先・行(現在点)

 Dim org As Worksheet
 Set org = Worksheets("UniMap")
 Dim cpy As Worksheet
 Set cpy = Worksheets("UniMap2")
 Dim sheet1 As Worksheet

 i = 2
 j = -10
 Do While org.Cells(i, 1).Value <> ""
  k = org.Cells(i, 1).Value       ' 区
  t = org.Cells(i, 2).Value       ' 点
  If org.Cells(i, 3).Value < "A1A1" Then
   m = 1                ' 面
  Else
   m = 2                ' 面
  End If
 ' 点01のとき
  If t = 1 Then
   j = j + 12
   Application.ScreenUpdating = True
   cpy.Cells(j, 1).Select
   Application.ScreenUpdating = False
   Call setKeisen(j)
   cpy.Cells(j, 1).Value = m      ' 面
   cpy.Cells(j, 2).Value = k      ' 区
   cpy.Cells(j, 4).Value = Hex(Int("&H" & org.Cells(i, 3).Value) - 1)
   cpy.Cells(j, 5).Value = Hex(Int("&H" & org.Cells(i, 4).Value) - 1)
  End If
  p = j + (t \ 16) * 2
  n = t Mod 16 + 6
  If n = 6 Then
   cpy.Cells(p, 4).Value = org.Cells(i, 3).Value
   cpy.Cells(p, 5).Value = org.Cells(i, 4).Value
  End If
  cpy.Cells(p + 1, n).Value = org.Cells(i, 5).Value
  cpy.Cells(p, n).Value = org.Cells(i, 6).Value
  i = i + 1
 Loop

 cpy.Rows("2:" & (j + 11)).EntireRow.AutoFit
 Range("A1").Select
 Application.ScreenUpdating = True
 Range("A2").Select

End Sub

Private Sub setKeisen(i As Long)
 Dim j As Long
 Dim k As Long
 Application.ScreenUpdating = False
 Worksheets("UniMap2").Select

' 大枠罫線+縦罫線
 Range(Cells(i, 1), Cells(i + 11, 21)).Select
 With Selection
  .Borders(xlEdgeLeft).LineStyle = xlContinuous
  .Borders(xlEdgeLeft).Weight = xlMedium
  .Borders(xlEdgeTop).LineStyle = xlContinuous
  .Borders(xlEdgeTop).Weight = xlMedium
  .Borders(xlEdgeBottom).LineStyle = xlContinuous
  .Borders(xlEdgeBottom).Weight = xlMedium
  .Borders(xlEdgeRight).LineStyle = xlContinuous
  .Borders(xlEdgeRight).Weight = xlMedium
  .Borders(xlInsideVertical).LineStyle = xlContinuous
  .Borders(xlInsideVertical).Weight = xlThin
 End With
' 中間横線
 For j = i + 1 To i + 9 Step 2
  Range(Cells(j, 3), Cells(j, 21)).Select
  With Selection
   .Borders(xlEdgeBottom).LineStyle = xlContinuous
   .Borders(xlEdgeBottom).Weight = xlThin
  End With
 Next j
' 中間横破線
 For j = i To i + 10 Step 2
  Range(Cells(j, 6), Cells(j, 21)).Select
  With Selection
   .Borders(xlEdgeBottom).LineStyle = xlContinuous
   .Borders(xlEdgeBottom).Weight = xlHairline
  End With
 Next j
' 結合セル
 For j = i To i + 10 Step 2
  For k = 1 To 5
   Range(Cells(j, k), Cells(j + 1, k)).Select
   Selection.Merge
  Next k
 Next j

 Cells(i, 3).Value = "00"
 Cells(i + 2, 3).Value = "16"
 Cells(i + 4, 3).Value = "32"
 Cells(i + 6, 3).Value = "48"
 Cells(i + 8, 3).Value = "64"
 Cells(i + 10, 3).Value = "80"

 Range(Cells(i, 6), Cells(i + 1, 6)).Select
 Selection.Interior.ColorIndex = 24
 Range(Cells(i + 10, 21), Cells(i + 11, 21)).Select
 Selection.Interior.ColorIndex = 24

 For j = i To i + 10 Step 2
  Range(Cells(j, 6), Cells(j, 21)).Select
  Selection.Font.Name = "MS P明朝"
  Selection.Font.Size = 20
  Selection.Font.Bold = True
 Next j
 For j = i + 1 To i + 11 Step 2
  Range(Cells(j, 6), Cells(j, 21)).Select
  Selection.Font.Name = "HGゴシックM"
  Selection.Font.Size = 10
 Next j

End Sub
ブログオーナー
修正① SJIS算定ロジックの追加
↑前回の、課題の解決案の改良版で
JISの第4水準のコードが扱えるようになったのですが、
(SJISは入力になく、算定で求めている)
SJIS算定のロジックは、第2面のコードで
ポロポロでした。
なので、Jis2SJisに、2面のコード用のロジックを追加してみました。
一応、うまく行っているとは思いますが・・・
(勿論、バグありの可能性は否定できず、保証はしません←今までの分も全部そうです。)

************************************************************
Private Function Jis2SJis(jis As String) As String
 Dim hi As Long
 Dim lo As Long
 hi = "&H" & Left(jis, 2)
 lo = "&H" & Right(jis, 2)
 If hi > &H80 Then     ' 2面
  If (hi Mod 2) = 1 Then
   lo = lo - &H61
  Else
   lo = lo - &H2
  End If
 Else
  If hi And 1 Then
   If lo < &H60 Then
    lo = lo + &H1F
   Else
    lo = lo + &H20
   End If
  Else
   lo = lo + &H7E
  End If
 End If
 If hi < &H5F Then
  hi = (hi + &HE1) \ 2
 ElseIf hi < &H80 Then
  hi = (hi + &H161) \ 2
 ElseIf hi < &HA8 Then
  hi = (hi + &H13F) \ 2
 ElseIf hi = &HA8 Then
  hi = &HF0
 ElseIf hi < &HB0 Then
  hi = (hi + &H139) \ 2
 Else
  hi = (hi + &HFB) \ 2
 End If
 Jis2SJis = CStr(Hex(hi * &H100 + lo))
End Function
ブログオーナー
課題の解決案の改良版
どうせなら、ダウンロードも
EXCELにさせてしまおうということで、
改良してみました。

*************************************************************
Private Declare Function DeleteUrlCacheEntry Lib "wininet" Alias _
         "DeleteUrlCacheEntryW" (ByVal lpszUrlName As Long) As Long

Private Declare Function URLDownloadToFile Lib "urlmon" Alias _
         "URLDownloadToFileW" (ByVal pCaller As Long, _
                    ByVal szURL As Long, _
                    ByVal szFileName As Long, _
                    ByVal dwReserved As Long, _
                    ByVal lpfnCB As Long) As Long

Sub UniMap()
 Dim strTxt  As String: strTxt = "jisx0213-2004-8bit-std.txt"    ' OPENするファイル名
 Dim FilePath As String: FilePath = ThisWorkbook.Path & "" & strTxt ' フルパス
 Dim Url   As String:   ' DOWNLOADするファイル名(URL)
 Dim intFF  As Integer   ' FreeFile値
 Dim Buf   As String   ' 入力レコード
 Dim Rec   As Variant   ' 入力データ
 Dim tmp   As Variant   ' セル
 Dim jisCd  As String   ' JISコード
 Dim SjisCd  As String   ' Shift-JISコード
 Dim uniCD  As String   ' Unicode
 Dim uniCD2  As String   ' Unicode 2つ目
 Dim MoJI   As String   ' 文字
 Dim i    As Long
 Dim j    As Long: j = 1 ' シート行
 Dim ret   As Long: ret = 0
' ダウンロード(ファイルが無い場合)
 If Dir(FilePath) = "" Then
  Url = "http://x0213.org/codetable/" & strTxt
  DeleteUrlCacheEntry StrPtr(Url) 'キャッシュクリア
  ret = URLDownloadToFile(0, StrPtr(Url), StrPtr(FilePath), 0, 0)
  If ret <> 0 Then
   MsgBox "ダウンロード処理が失敗しました。", vbCritical + vbSystemModal
   Exit Sub
  End If
 End If
 Worksheets("UniMap").Select
' ファイルOPEN(入力モード)
 intFF = FreeFile
 Open FilePath For Input As #intFF
 Line Input #1, Buf
' ファイルCLOSE
 Close #intFF
' レコードに分割
 Rec = Split(Buf, vbLf)
 For i = 0 To UBound(Rec) - 1
  tmp = Split(Rec(i), vbTab)
  If Left(tmp(0), 2) <> "##" Then
   If Mid(tmp(1), 3) <> "" Then        ' UniCode(HEX)あり?
    j = j + 1
    uniCD = Mid(tmp(1), 3)
    jisCd = Right(tmp(0), 4)         ' JISCODE編集
    Cells(j, 1).Value = Int("&H" & Left(jisCd, 2)) - 32 ' 区
    If Cells(j, 1).Value > 128 And _
      Cells(j, 1).Value <> Cells(j - 1, 1).Value Then
      Cells(j, 7).Value = "2面"
      Cells(j, 8).Value = (Cells(j, 1).Value - 128) & "区"
    End If
    Cells(j, 2).Value = Int("&H" & Right(jisCd, 2)) - 32 ' 点
    Cells(j, 3).Value = jisCd        ' JISCODE(HEX)
   ' JIS(16進数) ==> S-JIS(16進数)
    SjisCd = Jis2SJis(jisCd)
    Cells(j, 4).Value = SjisCd        ' Shift-JIS(HEX)
    uniCD = Mid(tmp(1), 3)
    Cells(j, 5).Value = uniCD        ' UTF16
   ' UniCode(16進数) ==> 文字
    If InStr(uniCD, "+") > 0 Then
     uniCD = Left(uniCD, InStr(uniCD, "+") - 1)
     uniCD2 = Cells(j, 5).Value
     uniCD2 = Mid(uniCD2, InStr(uniCD2, "+") + 1)
     Cells(j, 5).Interior.ColorIndex = 6
    Else
     uniCD2 = ""
    End If
    If ("&H" & uniCD) < &H10000 Then
     MoJI = ChrW("&H" & uniCD)      ' 文字(1面)
    Else
     MoJI = ChrW_SP("&H" & uniCD)     ' 文字(2面)
     Cells(j, 6).Interior.ColorIndex = 6
    End If
    Cells(j, 6).Value = MoJI        ' 文字
    If uniCD2 <> "" Then
     Cells(j, 6).Value = Cells(j, 6).Value & ChrW("&H" & uniCD2)
    End If
    If j = Int(j / 25) * 25 Then
     Application.ScreenUpdating = True
     Cells(j, 6).Select
     Application.ScreenUpdating = False
    End If
   End If
  End If
 Next i
 Range(Cells(1, 1), Cells(j, 6)).Select
 Selection.Borders.LineStyle = xlContinuous
 Application.ScreenUpdating = True
 Cells(j, 3).Select
 MsgBox "JIS UTF16 対照リスト 完了!"
 Cells(1, 3).Select
 Cells(2, 3).Select
' ファイル削除
 If Dir(FilePath) <> "" Then
  If MsgBox("ダウンロードした以下のファイルを削除しますか?" & _
        vbNewLine & FilePath, vbYesNo) = vbYes Then
   Kill FilePath
  End If
 End If
End Sub
ブログオーナー
課題の解決案
探せば、あるものですね。
JIS X 0213利用者有志による、相互扶助を目的としたウェブサイト というサイトに
http://x0213.org/
・JIS X 0213:2004 漢字8ビット符号とUnicodeの対応表
http://x0213.org/codetable/jisx0213-2004-8bit-std.txt
というのがあって、それを入力にして、同様の文字コード表を作ってみました。
function は前回コメントまでと同じものを利用。

そこにあるのだから、EXCELにする必要あるか?
というそもそもの疑問は、あるのですが・・・
まあ、成り行き上

で、出来た文字リストなんですが、
↑EXCEL VBA 関数(ASCW)で作成した記事本文のリストの文字と若干違うものがあり
僕のPC(VISTA)、または、EXCEL(2007)が変更に対応できていないためか・・・と
思っているんですが・・・

********************************************************************************
Sub UniMap()
 Dim intFF As Integer    ' FreeFile値
 Dim strTxt As String: strTxt = ThisWorkbook.Path & _
                "\jisx0213-2004-8bit-std.txt"
 Dim Buf  As String     ' 入力レコード
 Dim tmp  As Variant    ' セル
 Dim i   As Long: i = 1  ' シート行
 Dim jisCd As String     ' JISコード
 Dim SjisCd As String     ' Shift-JISコード
 Dim uniCD As String     ' Unicode
 Dim uniCD2 As String     ' Unicode 2つ目
 Dim MoJI  As String     ' 文字
 Worksheets("UniMap").Select
' ファイルOPEN(入力モード)
 intFF = FreeFile
 Open strTxt For Input As #intFF
 Do Until EOF(intFF)
  Line Input #intFF, Buf
  tmp = Split(Buf, vbTab)
  If Left(tmp(0), 2) <> "##" Then
   If Mid(tmp(1), 3) <> "" Then        ' UniCode(HEX)あり?
    i = i + 1
    uniCD = Mid(tmp(1), 3)
    jisCd = Right(tmp(0), 4)         ' JISCODE編集
    Cells(i, 1).Value = Int("&H" & Left(jisCd, 2)) - 32 ' 区
    Cells(i, 2).Value = Int("&H" & Right(jisCd, 2)) - 32 ' 点
    Cells(i, 3).Value = jisCd        ' JISCODE(HEX)
   ' JIS(16進数) ==> S-JIS(16進数)
    SjisCd = Jis2SJis(jisCd)
    Cells(i, 4).Value = SjisCd        ' Shift-JIS(HEX)
    uniCD = Mid(tmp(1), 3)
    Cells(i, 5).Value = uniCD        ' UTF16
   ' UniCode(16進数) ==> 文字
    If InStr(uniCD, "+") > 0 Then
     uniCD = Left(uniCD, InStr(uniCD, "+") - 1)
     uniCD2 = Mid(uniCD, InStr(uniCD, "+") + 1)
    Else
     uniCD2 = ""
    End If
    If ("&H" & uniCD) < &H10000 Then
     MoJI = ChrW("&H" & uniCD)      ' 文字(1面)
    Else
     MoJI = ChrW_SP("&H" & uniCD)     ' 文字(2面)
     Cells(i, 6).Interior.ColorIndex = 6
    End If
    Cells(i, 6).Value = MoJI        ' 文字
    If uniCD2 <> "" Then
     Cells(i, 7).Value = ChrW("&H" & uniCD2)
    End If
    If i = Int(i / 25) * 25 Then
     Application.ScreenUpdating = True
     Cells(i, 6).Select
     Application.ScreenUpdating = False
    End If
   End If
  End If
 Loop
' ファイルCLOSE
 Close #intFF
 Range(Cells(1, 1), Cells(i, 6)).Select
 Selection.Borders.LineStyle = xlContinuous
 Application.ScreenUpdating = True
 Cells(i, 3).Select
 MsgBox "JIS UTF16 対照リスト 完了!"
 Cells(1, 3).Select
 Cells(2, 3).Select
End Sub
ブログオーナー
課題 行き詰まり
文字コードは、仕事で使う場合もまあ、最初から決まっていて
(インフラさんのお仕事)
それを前提に開発とか保守とかしている訳で
恥ずかしながら、そんなに調べたことが無かったです。

ネットに提供されている文字コード表で
JIS第3水準とか、JIS第4水準とかがあります。

今回、僕が作った(というか寄せ集めなんで加工したなんですが)
には、含まれていない。

というか、JIS第3水準は、実は入っているのですが
フォントにないので、出ない様になっているのです。

フォントにないのに何故、ネットで検索したページの字は出て来る?

不思議ですね。
調べてみると
ネットのページは、UNICODEで表示させている。

だから、表示される。

JIS第4水準は、区点のコード空間ではもう足りないので、
そもそも、面が出てきて、
UNICODEありきのコードになっている。

EXCEL関数の、ASCでは、もうお手上げな訳です。

そもそもが、JIS <==> UNICODE は、計算による変換ではなく
対照表による変換なので、

その対照表がないかなと・・・
いうことに

JISコードの2面の作成マクロは、よって未完です。
今のところ
⇒画像
追加① unicode文字コード2面
http://blogimg.goo.ne.jp/user_image/0d/a0/55025b2064c49b51974ff9f9ef68db07.jpg
ネットを検索すれば、
http://wakufactory.jp/densho/font/utf.html とか
UNICODEの一覧なんてすぐに見つかるので・・・
意味があるかどうか

は、さておいて

これを進めて、次の段階(文字の出現調査や、外字の使用等)の
前提になるかもで、作成してみました。(またまた、ネットのモザイクソースですが・・・)

Unicode の文字コード表(2面)

要るかあそんなの・・・(まあまあ)

************************************************************
Sub uniCdTbl()
 Dim i   As Long
 Dim j   As Long
 Dim uniCD As Long
 Dim uniHex As String
 Dim MoJI  As String
 
 Worksheets("2面").Select
 j = 1
 For i = 1 To 65536
  uniCD = i + 131071
 ' If uniCD < 180224 Or _      ' U+2C000
 '  uniCD > 192511 Then      ' U+2EFFF
  If uniCD < 173792 Then      ' 使用領域のみ表示
   j = j + 1
   MoJI = ChrW_SP(uniCD)         ' 文字
   If j = 2 Then
    Cells(j, 1).Value = "02"      ' A:02面固定
   End If
   uniHex = Hex(uniCD)          ' D:UTF16(HEX)
   Cells(j, 2).Value = Mid(uniHex, 2, 2) ' B:区
   Cells(j, 3).Value = Right(uniHex, 2) ' C:点
   Cells(j, 4).Value = uniHex      ' D:UTF16(HEX)
   Cells(j, 5).Value = uniCD       ' E:UTF16(10進数)
   Cells(j, 6).Value = MoJI       ' F:文字
   If j = Int(j / 100) * 100 Then
    Application.ScreenUpdating = True
    Cells(j, 4).Select
    Application.ScreenUpdating = False
   End If
  End If
 Next i
 Range(Cells(1, 2), Cells(j, 6)).Select
 Selection.Borders.LineStyle = xlContinuous
 Application.ScreenUpdating = True
 Cells(j, 4).Select
 MsgBox "UTF16 2面リスト 完了!"
 Cells(1, 4).Select
 Cells(2, 4).Select
End Sub

Private Function ChrW_SP(ByVal CharCode As Long) As String
Dim HS As Long '上位サロゲート
Dim LS As Long '下位サロゲート

 If CharCode < &H10000 Then Exit Function
 CharCode = CharCode - &H10000   '元のコードから&H10000を引く
 HS = (CharCode \ &H400) + &HD800  '上位:&H400で割った商に&HD800を足す
 LS = (CharCode Mod &H400) + &HDC00 '下位:&H400で割ったあまりに&HDC00を足す
 ChrW_SP = ChrW(HS) & ChrW(LS)   '連結
End Function
名前:
コメント:

※文字化け等の原因になりますので顔文字の投稿はお控えください。

コメント利用規約に同意の上コメント投稿を行ってください。

 

※ブログ作成者から承認されるまでコメントは反映されません。

  • Xでシェアする
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

最新の画像もっと見る

最近の「EXCEL VBA」カテゴリーもっと見る

最近の記事
バックナンバー
人気記事