Access引越し中小企業のAI導入支援|古い業務システムの作り直しからAccess・オフコンの引越し 専門

コラム仕組みと実験

データ移行で文字化けするのはなぜ?Shift_JIS・CP932・外字の違いを数えた

データ移行の文字化けは、移す前と後で文字コードの表が違うために起きます。Pythonで数えると、WindowsのShift_JIS(cp932)にしかない字が454字、外字の領域が1,880字ありました。髙・﨑・①・㈱や社内で作った外字が、移した先で「?」や別の字になります。Access引越しでは、移す前に化けそうな字を数えてから移します。(2026年10月時点)

全体の流れと費用はAccess・オフコンの引越しのページにまとめています。

要点

  • データ移行の文字化けは、移す前と後で文字コードの表が違うために起きます。
  • Python 3.14.2で数えると、shift_jisで書ける字は6,944、cp932は9,280でした。
  • cp932だけにある字は454字で、そのうち360字が髙・﨑などの漢字です。
  • 外字の領域F040〜F9FCは1,880字分あり、どの字かは元のPCの外字フォントで決まります。
  • 移す前にCSVの中の外字・cp932だけの字・書き換わる字を数えれば、直す字の一覧が作れます。
目次
  1. データ移行で文字が化けるのは、なぜですか?
  2. Shift_JISとCP932は、どれくらい違うのですか?
  3. 外字は、なぜ移すと字が分からなくなるのですか?
  4. 「〜」や「−」が別の字に変わるのは、なぜですか?
  5. 移す前に、化けそうな字をどう数えればよいですか?
  6. このサイトで相談するには?
  7. よくある質問

データ移行で文字が化けるのは、なぜですか?

移す前と後で、文字コードの表が違うためです。古いAccessやオフコンから書き出したCSVは、Shift_JIS系の表で書かれていることが多くあります。一方、新しい仕組みはUTF-8で読むのがふつうです。2つの表のどちらにも無い字や、同じ番号に別の字を割り当てている字が、移した先で「?」や別の字になります。

化け方は、次の4つに分かれます。数はPython 3.14.2のcodecsで数えた計算値です。

化け方 例 移すと起きること 数
cp932だけにある字 髙 﨑 ① Ⅱ ㈱ № shift_jisとして読むと「?」になる 454字
外字 社内で作った人名の字 私用領域の番号だけ移り、字が分からなくなる 領域は1,880字分
書き換わる字 〜 − ‖ ¢ £ ¬ 似た別の字(~ - ∥ など)に変わる 6か所
cp932で書けない字 𠮷 鷗 絵文字 Shift_JISの仕組みへ戻すときに止まる 表の外

Accessの中は、MicrosoftのドキュメントによるとUnicodeで文字を持っています。化けるのは、CSVに書き出すときと、新しい仕組みがそのCSVを読み込むときです。

shift_jisとcp932で書ける字の数を比べた横棒グラフ。共通は6,942字。shift_jisは計6,944字、cp932は計9,280字で、cp932だけの字が454字、私用領域が1,884字(外字の領域1,880字を含む)shift_jis と cp932 で書ける字の数shift_jis共通 6,942計 6,944字cp932共通 6,942計 9,280字cp932 だけの字 454私用領域 1,884(外字の領域 1,880 を含む)計算値:Python 3.14.2 の codecs で U+0080〜U+2FFFF を1字ずつ符号化して数えた(2026年10月、Access引越し 主宰)
図1 shift_jisとcp932で書ける字の数。主宰がPython 3.14.2のcodecsで1字ずつ符号化して数えた計算値です(2026年10月)。

Shift_JISとCP932は、どれくらい違うのですか?

書ける字の数が2,336字違います。U+0080〜U+2FFFFの字を1字ずつ符号化して数えると、shift_jisは6,944字、cp932は9,280字でした。名前はどちらも「Shift_JIS」と呼ばれがちですが、Pythonでは別の表として扱います。

cp932はWindowsのShift_JISで、shift_jisは元の規格の表です。Pythonでは「ms932」「windows-31j」もcp932と同じ表を指します。差の内訳は、cp932だけにある字が454字、私用領域が1,884字です。逆にshift_jisだけにある字は「¥」(U+00A5)と「‾」(U+203E)の2字でした。

454字の中身を分けると、漢字が360字でいちばん多く、髙・﨑・德・隆などの人名・地名によく出る字が入ります。残りは㈱や㎡などの単位が36字、①〜⑳が20字、ローマ数字が20字、№や℡などの記号が18字です。得意先マスタや社員の台帳ほど、この454字に当たりやすくなります。

cp932だけにある454字の内訳を示す横棒グラフ。漢字360字(互換漢字34字を含む)、単位や㈱など36字、丸数字20字、ローマ数字20字、記号など18字cp932 だけにある 454 字の内訳漢字360髙 﨑 德 隆 など(互換漢字 34 を含む)単位・㈱など36㈱ ㈲ ㌔ ㎡ ㍻ など丸数字20① 〜 ⑳ローマ数字20Ⅰ〜Ⅹ と ⅰ〜ⅹ記号など18№ ℡ ∑ ~ - ¬ など計算値:Python 3.14.2 の codecs で U+0080〜U+2FFFF を1字ずつ符号化して数えた(2026年10月、Access引越し 主宰)
図2 cp932だけにある454字の内訳。Unicodeの範囲で分けた計算値です。

外字は、なぜ移すと字が分からなくなるのですか?

外字は字の形ではなく、番号だけがデータに入っているためです。cp932の外字の領域は0xF040〜0xF9FCです。ここはUnicodeの私用領域U+E000〜U+E757の1,880字に対応します。Pythonで0xF040を読むとU+E000、0xF9FCを読むとU+E757になりました。

その番号にどんな字を描くかは、元のPCに入っている外字フォントが決めています。Microsoftのドキュメントも、外字や私用領域の字はPCごとに割り当てが違うと書いています。割り当てが無いこともあります。新しい仕組みに番号だけ移しても、同じフォントが無ければ空白や四角で出ます。

外字は消さずに、次の順で一覧にします。

  1. データの中の私用領域の字を数え、番号ごとに何件あるかを出す
  2. 元のPCの外字フォントで、その番号に描かれた字を確かめる
  3. 番号ごとに、Unicodeにある字(例:髙)へ置き換えるか、新しい仕組みで外字として扱うかを決める

「〜」や「−」が別の字に変わるのは、なぜですか?

同じバイトに、shift_jisとcp932が別の字を割り当てているためです。2バイトの範囲を全部読み比べると、違うのは6か所でした。たとえば0x8160は、shift_jisでは「〜」(U+301C)、cp932では「~」(U+FF5E)になります。

同じバイトをshift_jisとcp932で読んだときに字が変わる6か所の表。0x8160は〜と~、0x8161は‖と∥、0x817Cは−と-、0x8191は¢と¢、0x8192は£と£、0x81CAは¬と¬同じバイトでも、読む表で字が変わる6か所バイトshift_jis で読むとcp932 で読むと0x8160〜 U+301C~ U+FF5E0x8161‖ U+2016∥ U+22250x817C− U+2212- U+FF0D0x8191¢ U+00A2¢ U+FFE00x8192£ U+00A3£ U+FFE10x81CA¬ U+00AC¬ U+FFE2計算値:Python 3.14.2 の codecs で 0x8140〜0xFCFC の2バイトを両方の表で読んで比べた(2026年10月、Access引越し 主宰)
図3 読む表で字が変わる6か所。0x8140〜0xFCFCの2バイトを両方の表で読んで比べた計算値です。

見た目はほぼ同じでも、Unicodeでは別の字です。「10/15〜10/16」で検索しても、移した後のデータが「~」なら当たりません。品名や備考を突き合わせるときに、件数が合わない原因になります。

この6か所は、Pythonの表での結果です。製品によって表は少し違います。MySQLのドキュメントによると、0x815Fはsjisなら「\」(U+005C)、cp932なら「\」(U+FF3C)になります。移行先の製品で1件ずつ試すのが確実です。

移す前に、化けそうな字をどう数えればよいですか?

書き出したCSVを1字ずつ調べ、外字・cp932だけの字・書き換わる字・cp932で書けない字の4つに分けて数えます。私はこのためのスクリプト scripts/figs/mojibake_count.py を使っています。お使いのPCの中だけで動き、データを外に送りません。

def kind(ch):
    o = ord(ch)
    if o < 0x80: return None
    if 0xE000 <= o <= 0xF8FF: return '外字'
    if ch in SIX or ch in SIX.values(): return '書き換わる6字'
    if not can(ch, 'cp932'): return 'cp932で書けない'
    if not can(ch, 'shift_jis'): return 'cp932だけ'

架空の得意先マスタ10行で試しました。外字が2回、cp932だけの字が7種類、書き換わる字とcp932で書けない字が3種類ずつ見つかりました。結果には、字ごとに最初の出現位置(行と列)が出ます。この一覧が、そのまま「直す字の表」の下書きになります。

限界もあります。数えられるのはPythonの表で判定できる範囲です。外字が本当はどの字かは、元のPCのフォントを見ないと分かりません。オフコンの独自の文字コードは、CSVに書き出した後のデータで数えます。

このサイトで相談するには?

文字化けが心配なデータも、お見せいただかなくて構いません。何をどう頼むか決まっていなくても大丈夫です。

Access引越しが今の仕組みをうかがい、御社のやり方に合わせて、進め方を一緒に考えます。準備は要りません。無料で相談するからお声がけください。

よくある質問

移行先をUTF-8にすれば、文字化けは起きませんか?
いいえ、外字は残ります。UTF-8は髙や﨑を持てますが、外字は私用領域の番号のまま移るので、元の字に置き換える一覧が要ります。
外字が何字あるかは、どこで分かりますか?
データの中の私用領域U+E000〜U+F8FFの字を数えれば分かります。元のPCの外字フォントを開くと、その番号に描かれた字も確かめられます。
Shift_JISの仕組みへ戻すときも気をつけますか?
はい。𠮷・鷗・絵文字はcp932に無いため、書き出しが止まるか「?」になります。戻す前に同じスクリプトで数えておきます。
データを外に出さずに数えられますか?
はい。スクリプトはお使いのPCの中だけで動き、字の種類と行・列の位置を出すだけです。中身はどこにも送りません。

この数字の出し方

この記事の自前の数字は、次の見本・条件・回数で出しました。主宰が確かめ、更新日は2026年10月17日です。スクリプトの名前から、同じ手順を自分のファイルで再現できます。

  • Access引越しの計算(2026年10月16日、Python 3.14.2 の codecs で1字ずつ符号化。shift_jis 6,944字・cp932 9,280字)。scripts/figs/mojibake_count.py

出典

  1. Python 標準ライブラリ codecs(標準エンコーディング cp932・shift_jis、エラーハンドラ)(2026年10月16日確認)
  2. Microsoft Learn「End-User-Defined and Private Use Area Characters」(2025年3月更新)(2026年10月16日確認)
  3. Microsoft Learn「EUDCCodeRange」(932=F040-F9FC、Unicode=E000-F8FF)(2026年10月16日確認)
  4. Microsoft Learn「About compressing the data in a Text, Memo, or Hyperlink field」(Access は Unicode で文字を持つ)(2026年10月16日確認)
  5. MySQL 8.0 リファレンスマニュアル 10.10.7.1「cp932 文字セット」(2026年10月16日確認)