[[20110901234526]] 『文字の抽出について』(サンジ) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『文字の抽出について』(サンジ)

 [エクセルのバージョン]  Excel2007
 [OSのバージョン]  WindowsXP

 いつも お世話になってます。
 何千もの名前(個人名・会社名)と住所の文字化けを抽出し、最終的に『◆』にたいのですけど、
 画面をスクロールしながら睨みつけるように何度も見て、やっと探しだしたと思っても、
 実際まだ残っており、どうしたものかと悩んでおります。

 A列を検索列にして、名前や住所を貼りつけて(文字は全部全角)
 B列に下記以外の、記号も含む文字などだけを抽出できたらと思います。

      全角スペース
     全角ひらがな
      全角カタカナ
      全角数字
      全角英字(大文字)
      全角英字(小文字)      
      第一水準漢字
      第二水準漢字
      ー − ・ ( ) ? & 〜 : / , . _ 梶@

 最後の行は増える可能性がありますので、できましたらコードに追加できるように・・・

 そしてそれから、
 B列に抽出された文字を確認して(◆にしなくてもいいものがあれば消したりして)、
 そのあと、B列に抽出されたものを、A列で◆にします。 

 そんな夢のようなマクロを
 教えていただけませんでしょうか?

 よろしくお願い致します。


 この辺りが参考になりそうですが。。。
[[20061002073914]]『JISコード以外の字を使わない方法は』(IVIO)
[[20050808102534]]『シフトJIS第3・4水準文字を調べたい。』(かな)

 紹介のみです。。。

 (HANA)

 HANA様
 まだ途中ですが、
 紹介してもらったマクロの、コードを調べて、削除&追加して試してみました。

 Option Explicit
 '--------------------------------------------------------------------------------
 Function GetOtherString(ByVal Target As Range) As String
     Dim intIdx As Integer
     Dim strWk As String
     Dim Ret As String
     Dim r As Range
     Ret = ""

     For Each r In Target
         For intIdx = 1 To Len(r.Value)
             strWk = Mid(r.Value, intIdx, 1)

             If IsOtherChar(strWk) Then
                 Ret = Ret & strWk
             End If
         Next
     Next
     GetOtherString = Ret
 End Function
 '--------------------------------------------------------------------------------
 Public Function IsOtherChar(ByVal strTarget As String) As Boolean
     Dim bytWk() As Byte
     Dim blnFlg As Boolean

     IsOtherChar = False
     blnFlg = False
     If strTarget = "?" Then       '本当の?と区別の為
     Else
         Erase bytWk
          bytWk = StrConv(strTarget, vbFromUnicode)
         If UBound(bytWk) < 1 Then      '1Byte文字
             If bytWk(0) = &H3F Then    'JIS範囲外文字
                 blnFlg = True
             End If
         Else               '2Byte文字
             If bytWk(1) >= &H0 And bytWk(1) <= &H3F Then  '不明
                 blnFlg = True

             ElseIf bytWk(1) = &H7F Then   '不明
                 blnFlg = True

            ElseIf bytWk(1) >= &HFD And bytWk(1) <= &HFF Then  '不明
                blnFlg = True

            ElseIf bytWk(0) = &H84 And bytWk(1) >= &H9F And bytWk(1) <= &HA0 Then   '全角文字(―|)
            ElseIf bytWk(0) = &H82 And bytWk(1) >= &H4F And bytWk(1) <= &H58 Then   '全角文字(数字)
            ElseIf bytWk(0) = &H82 And bytWk(1) >= &H60 And bytWk(1) <= &H79 Then   '全角文字(英字大文字)
            ElseIf bytWk(0) = &H82 And bytWk(1) >= &H81 And bytWk(1) <= &H9A Then   '全角文字(英字小文字)
            ElseIf bytWk(0) = &H82 And bytWk(1) >= &H9F And bytWk(1) <= &HF1 Then   '全角文字(ひらがな)
            ElseIf bytWk(0) = &H83 And bytWk(1) >= &H40 And bytWk(1) <= &H96 Then   '全角文字(カタカナ)
            ElseIf bytWk(0) = &H83 And bytWk(1) = &H92 And bytWk(1) = &H92 Then     '全角文字(ヲ)
            ElseIf bytWk(0) = &H81 And bytWk(1) = &H44 And bytWk(1) = &H44 Then     '全角文字(.)
            ElseIf bytWk(0) = &H81 And bytWk(1) = &H45 And bytWk(1) = &H45 Then     '全角文字(・)
            ElseIf bytWk(0) = &H81 And bytWk(1) = &H69 And bytWk(1) = &H69 Then     '全角文字(()
            ElseIf bytWk(0) = &H81 And bytWk(1) = &H6A And bytWk(1) = &H6A Then     '全角文字())
            ElseIf bytWk(0) = &H81 And bytWk(1) = &H51 And bytWk(1) = &H51 Then     '全角文字(_)
            ElseIf bytWk(0) = &H81 And bytWk(1) = &H95 And bytWk(1) = &H95 Then     '全角文字(求j
            ElseIf bytWk(0) = &H81 And bytWk(1) = &H5C And bytWk(1) = &H5C Then     '全角文字(―)
            ElseIf bytWk(0) = &H81 And bytWk(1) = &H5E And bytWk(1) = &H5E Then     '全角文字(/)
            ElseIf bytWk(0) = &H81 And bytWk(1) = &H40 And bytWk(1) = &H40 Then     '全角文字( )
            ElseIf bytWk(0) = &H87 And bytWk(1) = &H8A And bytWk(1) = &H8A Then     '全角文字(梶j
            ElseIf bytWk(0) = &H87 And bytWk(1) = &H8B And bytWk(1) = &H8B Then     '全角文字(求j          
                 blnFlg = True

            ElseIf bytWk(0) = &H88 And bytWk(1) >= &H9F Then      '第一水準漢字(亜〜
            ElseIf bytWk(0) > &H88 And bytWk(0) < &H98 Then       '第一水準漢字 (上2桁が88〜98の間の)
            ElseIf bytWk(0) = &H98 And bytWk(1) <= &H72 Then      '第一水準漢字    〜腕)
            ElseIf bytWk(0) = &H98 And bytWk(1) >= &H9F Then      '第二水準漢字(弌)
            ElseIf bytWk(0) > &H98 And bytWk(0) < &HEA Then       '第二水準漢字(俾)
            ElseIf bytWk(0) = &HEA And bytWk(1) <= &HA4 Then      '第二水準漢字(熙)
            Else       '不明
                blnFlg = True

            End If
        End If
    End If
    Erase bytWk
    If blnFlg Then
        IsOtherChar = True
    End If
 End Function

 汲表示されないようにしたつもりですが、なぜか、汲ェ どうしても表示されてしまうのです。
 どこが違うのか、、、、

 それと、エクセルの『記号と特殊文字』で使う文字は、全角に見えて、実は半角のものが多い事に気づきました。
 という事は、文字化けは、半角を◆にするマクロを使えば、ほとんどは解決するのではないかと。(サンジ)


            ElseIf bytWk(0) = &H87 And bytWk(1) = &H8B And bytWk(1) = &H8B Then     '全角文字(求j          
                 blnFlg = True
 って成っているから、表示されているのでは。。。?

 (HANA)

HANA様 あぁぁぁぁ、ほんとだ、ありがとうございます。
 見えてなかったです。消えました、さすがです。
 もうひとつ疑問なのが、全角カタカナ全部が表示されないように一行で記載しているのに、
 ヲ が なぜか表示されるので、ヲのコードだけ追加したら表示されないようになりました。
 なぜなのでしょうか?(サンジ)


          ElseIf bytWk(0) = &H83 And bytWk(1) = &H92 And bytWk(1) = &H92 Then     '全角文字(ヲ)
 この一行の事ですよね?
 こちらではこの一行が無くても「ヲ」は表示されませんが。。。?

 表示されるって事は、blnFlg = Trueの行を通っているので
 一旦「全角文字(ヲ)」の行はコメントアウト。

 コード内にブレークポイントを設定。
  コードを書く白い部分の左側に細く有る灰色の部分をクリックすると
  茶色い● が出ます。
  これが有る行で、処理が一旦中断します。
 その後、[F8]で一行ずつ実行させて思った分岐をしているか確認してみて下さい。

 数式が沢山あると面倒な事になるかもしれないので
 一つだけ数式を残して、他は削除。
 参照セルに「ヲ」だけ入れて再計算させると
 コードが実行されて、●をつけた行で止まると思います。

 「全角文字(カタカナ)」の分岐に
    MsgBox "全角文字(カタカナ)"
 の一行を追加して、メッセージボックスを表示させる様にしておくと
 分かりやすいかもしれません。

 (HANA)

わかりやすい説明、ありがとうございました。
 HANA様の説明どおりにやってみたら、ヲのコードなしでもできました。
 ブレークポイントを初めて試してみましたが、ほんとに勉強になって嬉しいです。
 (サンジ)

本日、本社でやてみました。(XP,2007)

 自宅のパソコンでは表示できなかった文字化けを調べたところ、『外字』というもので、
 外字のコードを入れて、 blnFlg = True  でやってみました。
 ところが、なぜか、表示されません。外字というのは なにか特別な文字なのでしょうか?
 (サンジ)


 外字は使った事が無いに等しいので、良く分からないのですが。。。

 IsOtherChar(strWk) が True に成るのに、
 GetOtherString = Ret
 で戻って来ないって事ですか?
(外字が登録されているパソコンで)

 ちなみに、外字は普通 F040 から登録されていると思うので
 特に何もしなくても
            Else       '不明
                blnFlg = True
 に分岐すると思います。

 一応 F040 に外字を登録して、GetOtherStringにかけてみましたが
 ちゃんと表示されましたよ?

 (HANA)

HANA様

 >一応 F040 に外字を登録して、GetOtherStringにかけてみましたが
 >ちゃんと表示されましたよ?
           ↓
      この言葉に勇気付けられます!

 >特に何もしなくても
 >           Else       '不明
 >               blnFlg = True
 >に分岐すると思います。
           ↓  
       そうなんですね。
       家のパソコン(ウィンドウズ 7)では出るのですが、会社のパソコンでは一文字も表示されません。
       なぜなのか・・・・

    @ パソコン →
         ・家(7、エクセル2007) 
       ・会社(XP、エクセル2007)
   A 文字化けの文字 → 
         ・7では、エクセルの挿入タグの特殊文字から出しています。(『外字(F040〜)』が全て『・』になっているので)
        ・XPのデータは、多分 他のものからエクセルに取り込んだ時に文字化けしたものと思われます。
             (XPの、特殊文字と外字の文字は微妙に違っており、
                           XPのデータの文字化け文字は、特殊文字ではなく、外字のほうでした。
                                                例:囲み□A とか、bの左上に゜とか、☎㎘括㈿など)
    B 半角の文字を◆にするマクロを実行 →
     ・7では、ほとんどの特殊文字が◆になりました。
      ・XPでは、全然変化なしです。
             (ここで、XPのデータの文字化けは確実に特殊文字ではないことが判りました。)
    C 調べていくうちに、見た目が同じような文字で『外字』『特殊文字』『機械(環境)依存文字』『ユニコード』があり、
       そんなこんなの不明な文字は、

 >           Else       '不明
 >               blnFlg = True 
                                   で、全部表示されるのではないかと思っているのですが・・・・
                                             どうもうまく行きません。 
 (サンジ)     

     

   


 自宅で試しているファイルと、会社で試しているファイルは違うファイル
 (内容や、データの由来が違う)なんですよね?

 それで 結局、会社のパソコンでは 該当の文字は
 IsOtherChar(strWk) が True に成っているのですか?
 成っている場合、何処で分岐していますか?
   想定通り最後の「不明」に分岐しているのでしょうか?
 また、その時に「strWk」の中身は何に成っていますか?

 ローカルウィンドウを表示させて確認してみて下さい。

 ただ、これまで私は
  とあるブックを別の人に渡す時に
  そのままだと文字化けする(今は文字化けしていない)から
  事前に確認して、文字化けしない文字に置き換えておきたい
 と言う事かと思っていましたが。。。違う様ですね?
 なんだか良く分からなく成って来ました。

 (HANA)

HANA様、すみません、説明が悪くて。
 >ただ、これまで私は
 > とあるブックを別の人に渡す時に
 > そのままだと文字化けする(今は文字化けしていない)から
 > 事前に確認して、文字化けしない文字に置き換えておきたい
 >と言う事かと思っていましたが。。。違う様ですね?
 >なんだか良く分からなく成って来ました。
        ↓
    会社のパソコンに入れてあるデータの文字化け文字を◆にする仕事をしています。

 > 自宅で試しているファイルと、会社で試しているファイルは違うファイル
 >(内容や、データの由来が違う)なんですよね?
     ↓
    そうです。

 > それで 結局、会社のパソコンでは 該当の文字は
 >IsOtherChar(strWk) が True に成っているのですか?
 >成っている場合、何処で分岐していますか?
 >  想定通り最後の「不明」に分岐しているのでしょうか?
 >また、その時に「strWk」の中身は何に成っていますか?
 >
 >ローカルウィンドウを表示させて確認してみて下さい。
         ↓
    明日、会社で確認してみます。ありがとうございます、すみませんでした。

 (サンジ)


会社のパソコンで F040で IsOtherChar(strWk) は、値が<変数なし>となっていて
 Falseでした。
 会社のパソコンで表示される F040は、電話のマークなんですけど、インターネットで調べると、トランプのスペードになっています。
 う〜ん・・・・??? (サンジ)


 >会社のパソコンに入れてあるデータの文字化け文字を◆にする仕事をしています。
 そういえば、最初にその様に書いてありましたね。。。
 すみません。

 >会社のパソコンで F040で IsOtherChar(strWk) は、値が<変数なし>となっていて
 >Falseでした。
 こちらも申し訳ありませんが、状況のご説明の日本語は分かりません。

 何かの文字が文字化けして、電話のマークに成っているのですよね?
 >F040で
 ってのは、何が F040 ですか?
 その、電話のマークのコードですか?
 これはどの様に調べたのでしょう?

 >IsOtherChar(strWk) は、値が<変数なし>となっていてFalseでした。
 strWk の値が「変数なし」になっていて
 IsOtherChar(strWk) が、False だったのですか?

 あ、「Public Function IsOtherChar」のコード内で確認したなら
 strTarget の中を確認してください。

 ちなみに、そのマークを一文字だけ切り取って、A1セルに入れてください。
 で、↓のコードを実行。

 '------
Sub TEST1()
Dim bytWk() As Byte
    bytWk = StrConv(Range("A1").Value, vbFromUnicode)
    If UBound(bytWk) >= 1 Then
        Range("B1").Value = "&H" & Hex(bytWk(0))
        Range("C1").Value = "&H" & Hex(bytWk(1))
    End If
End Sub
 '------

 B1セルに &HF0 、C1セルに &H40 が表示されますか?

 (HANA)

 なんかずいぶん昔のソースが。なつい。
どのように扱ってもらっても良いですが、私なら特別に弾きたい文字は
件の関数内に小難しく突っ込むのではなく、別にリストとして持って判定させるかなぁ。
文字コード的に飛び飛びの1文字を判定させるのに、わざわざコードの範囲指定する事もないだろうし。
 
以上、ちょろっと思った事でした。
あぁ、あと電話マークがスペード云々とかってフォントの違いだったりしないですか。
(ご近所PG)

HANA様、ご近所PG様、お世話になり、ありがとうございます。
 ご近所PG様、苦心されて作られた凄いコードを、勝手に使わせていただいてます、すみません。

 HANA様のコメントを、ひとことづつ すっと考えていると、いつも何かに気付かされます。
 TEST1を実行しました。B1セルに &HF0 、C1セルに &H40 が表示されました。

 >あ、「Public Function IsOtherChar」のコード内で確認したなら
 >strTarget の中を確認してください。
       ↓
     何回か 確認している途中で、文字コードが気になり・・・

 >何かの文字が文字化けして、電話のマークに成っているのですよね?
 >>F040で
 >ってのは、何が F040 ですか?
 >その、電話のマークのコードですか?
 >これはどの様に調べたのでしょう?
        ↓
   これは、IMEパット 文字一覧です。

 と、ここで気付きました。なんか違うような・・・・もっと詳しくコードが出る表があったような・・・
 ・・・すみません、スタートボタンの〔文字コード表〕のほうにも、同じようなコード表があり、そちらのほうでも見てみたら、

 ご近所PG様が書かれている様に、
 〔文字コード表〕の、フォントを変えると、表示される文字や数が全然違うことを知りました。

 フォント を、全フォント(外字)
 文字セット を、ウィンドウズ:日本語
 グループ を、すべて にして、コードを調べなおしたら、 
 会社のXPでは電話のマーク(f040)から、 b゜(f0d6)までのコードが表示されていました。
 (自宅のウィンドウス7では ここは全部空欄になってます)

 そこで、コードの Public Function より下を
 
 '--------------------------------------------------------------------------------
Public Function IsOtherChar(ByVal strTarget As String) As Boolean
    Dim bytWk() As Byte
    Dim blnFlg As Boolean

    IsOtherChar = False
    blnFlg = False
    If strTarget = "?" Then       '本当の?と区別の為
    Else
        Erase bytWk
        bytWk = StrConv(strTarget, vbFromUnicode)
        If UBound(bytWk) < 1 Then                                '1Byte文字
            If bytWk(0) = &H3F Then                              'JIS範囲外文字
                blnFlg = True
            End If
        Else                                                      '2Byte文字 
            If bytWk(1) >= &H0 And bytWk(1) <= &H3F Then       '不明
                blnFlg = True
            ElseIf bytWk(1) = &H7F Then   '不明
                blnFlg = True
            ElseIf bytWk(1) >= &HFD And bytWk(1) <= &HFF Then    '不明
                blnFlg = True
            ElseIf bytWk(0) >= &H0 And bytWk(0) <= &H10 Then    '外字を表示させる
                blnFlg = True

            ElseIf bytWk(0) = &H84 And bytWk(1) >= &H9F And bytWk(1) <= &HA0 Then   '全角文字(―|)
            ElseIf bytWk(0) = &H82 And bytWk(1) >= &H4F And bytWk(1) <= &H58 Then   '全角文字(数字)
            ElseIf bytWk(0) = &H82 And bytWk(1) >= &H60 And bytWk(1) <= &H79 Then   '全角文字(英字大文字)
            ElseIf bytWk(0) = &H82 And bytWk(1) >= &H81 And bytWk(1) <= &H9A Then   '全角文字(英字小文字)
            ElseIf bytWk(0) = &H82 And bytWk(1) >= &H9F And bytWk(1) <= &HF1 Then   '全角文字(ひらがな)
            ElseIf bytWk(0) = &H83 And bytWk(1) >= &H40 And bytWk(1) <= &H96 Then   '全角文字(カタカナ)

            ElseIf bytWk(0) = &H81 And bytWk(1) = &H44 Then     '全角文字(.)
            ElseIf bytWk(0) = &H81 And bytWk(1) = &H45 Then     '全角文字(・)
            ElseIf bytWk(0) = &H81 And bytWk(1) = &H69 Then     '全角文字(()
            ElseIf bytWk(0) = &H81 And bytWk(1) = &H6A Then     '全角文字())
            ElseIf bytWk(0) = &H81 And bytWk(1) = &H51 Then     '全角文字(_)
            ElseIf bytWk(0) = &H81 And bytWk(1) = &H95 Then     '全角文字(&)
            ElseIf bytWk(0) = &H81 And bytWk(1) = &H5C Then     '全角文字(―)
            ElseIf bytWk(0) = &H81 And bytWk(1) = &H5E Then     '全角文字(/)
            ElseIf bytWk(0) = &H81 And bytWk(1) = &H40 Then     '全角文字( )
            ElseIf bytWk(0) = &H87 And bytWk(1) = &H8A Then     '全角文字(梶j
            ElseIf bytWk(0) = &H87 And bytWk(1) = &H8B Then     '全角文字(求j

            ElseIf bytWk(0) = &H88 And bytWk(1) >= &HA0 Then      '第一水準漢字(唖〜
            ElseIf bytWk(0) > &H88 And bytWk(0) < &H98 Then       '第一水準漢字     上2桁が88〜98の間の
            ElseIf bytWk(0) = &H98 And bytWk(1) <= &H72 Then      '第一水準漢字                         〜腕)

          ’第二水準を表示させたくない時は カンマを取る
            'ElseIf bytWk(0) = &H98 And bytWk(1) >= &H9F Then      '第二水準漢字(弌〜
            'ElseIf bytWk(0) > &H98 And bytWk(0) < &HFC Then       '第二水準漢字     上2桁が98〜FCの間の
            'ElseIf bytWk(0) = &HFC And bytWk(1) <= &H4B Then      '第二水準漢字                         〜K)

            Else       '不明
                blnFlg = True

            End If
        End If
    End If
    Erase bytWk
    If blnFlg Then
        IsOtherChar = True
    End If
End Function

 と、少し変えてみたら、表示されました! 
 コードの上のあたりの ’2バイト文字 の最後のところに、一行 外字コード(上2桁)を追加したのと、
 下のあたりに、第二水準を表示する時はカンマを外すように変えました。

 第二水準で、あと十数個、表示しないようにしたい文字があるので、
 ’全角文字 の途中に、コードを追加しようと思っていますが・・・

 ご近所PG様、
 >私なら特別に弾きたい文字は
 >件の関数内に小難しく突っ込むのではなく、別にリストとして持って判定させるかなぁ。
      ↓
     もしかして・・・・文字をコピーして貼り付けるだけで、表示しなくできるような・・・感じのマクロですか?
     今の私の能力では、言われるようなコードを作るのは無理ですが、
     しばらくはこちらのマクロに追加追加で、使い続けていこうと思ってます。
     しかし、忘れず いつまでも待ってますので、
     いつか時間が空いた時に教えていただけると嬉しいです。よろしくお願いします。
(サンジ)


 F040 はシフトJISのコードで、外字用スペースです。 
 外字を作るときは大抵 F040 から作った文字を入れていきます。
 ので、おそらく会社用のPCにはなにか外字ソフトが入っているのでしょう。
(通行人)

 あんまり要件は見てないけど、特定の文字に関しての判定は、例えば
 
Sub test()
    Dim i As Integer
    Dim Ret As String
    Dim strWk As String
    Dim strData As String
    Ret = ""
    strData = "テスト&デバッグ"
    For i = 1 To Len(strData)
        strWk = Mid(strData, i, 1)
        If IsOkChar(strWk) Then
            Ret = Ret & strWk
        End If
    Next
    MsgBox Ret
End Sub
Function IsOkChar(ByVal Target As String) As Boolean
    Const cstOkChar As String = ".・()_&―/ 括"
    IsOkChar = False
    If InStr(cstOkChar, Target) > 0 Then
        IsOkChar = True
    End If
End Function
 
って感じで、特にコード化して考えなくて良い物ならこんな判定方法でもいいのかなぁと。
関数名とか適当なんで、まぁ適当に。考え方だけ。
(ご近所PG)

通行人様、そうなんですね〜。
 外字とは、好きな(中国語みたいな?)組み合わせで自分で作った文字を入力する場所のことなのですね。
 言われたように、会社のパソコン きっと何かのソフトが入っているのでしょうね〜。
 今まで10年ほど、そんなことは何も知らないまま、漢字など入力していました。アドバイス、今後の仕事に、とても参考になりました。

 ご近所PG様、ありがとうございます。やってみます!
 ただ、会社のパソコンで・・・なので、返事が大幅に遅れ気味で 申し訳ございません。
 (サンジ)

コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.