shift-jis と utf-8 の混在問題に関する記事(リンクリスト)に戻る
以下に文字コードを表す言葉して「文字コード」「エンコーディング」「キャラクターセット」という言葉が出てくるが、全て同じような物と認識して欲しい。
正確にはそれぞれ微妙に違うものだが、取りあえず同じと考えて差し支えない。
utf-8 と utf-16LE はエンコーディングは違うが、文字コードはどちらも UNICODE である。
実務では utf の違いを含めて文字コードとして扱った方が会話トラブルにならない。
キャラクターセットは日本ではエンコーディングごとに一つしかないが、英語ではイギリスとアメリカのキャラクターセットは違う。
スペイン語もスペインとメキシコとベネズエラでは違う。
日本ではエンコーディング以外に区別する必要がない。
utf-8標準でシステム開発する要点
・旧システムや他システムとの連携する時に使用する文字コード。
他社とのデータ連係に使用する文字コード
他社とテキストデータを受け渡す事は多いと思う。
人間の作業系で作業する場合は、Excelなどで受け渡すから文字コードが問題になる事はないが、大量のデータを特定システムに非依存な形式で渡す場合は、CSVかXMLなどのフォーマットでデータを受け渡す事になると思う。
CSVやXMLはテキストファイルなので、使用する文字コードに注意が必要だ。
CSVは昔から文字コードに shift-jis を使用する。
utf-8 を使用する事が可能になったのは Excel2016 からだ。
それ以前に使用しているCSVは shift-jis で間違いない。
また、オンラインバンクやクレジットカード会社からダウンロードされる決済履歴などのデータも shift-jis のCSVだ。
会計ソフトやERPなども shift-jis のCSVを使用している事が多い。
XML は規格上は原則 UNICODE のはずだが、現実には shift-jis の XML が使用されているケースも少なくない。
他社とCSVやXML形式のデータを連係する場合は、その文字コードは何なのか確認しておく必要がある。
また、連携先が複数社に及ぶ場合に、連携先によって文字コードが異なる場合もある。
この場合は文字コードの変換は避けられない。
自社の新システムを utf-8 ベースで開発するなら、shift-jis で連携したデータの文字コードは utf-8 に変換する必要がある。
また、こちらから他社にデータを送る場合は、逆に utf-8 から shift-jis に変換する必要がある。
連携先が古い UNIX の場合、文字コードに euc-jp を使用している場合もある。
これも shift-jis と同様の注意が必要だ。
旧システムや他システムとの連携する時に使用する文字コード
他システム連携について簡単に説明する。
社内で複数のシステムを運用している事は多い。
大半の会社はそうだろう。
社内のシステムとシステムは互いにデータ連係しているのがほとんどだと思う。
このように社内のシステムとシステムが互いにデータ連係する事を他システム連携と呼ぶ。
他システム連携の方法はいくつもあり、他社との連携より多様だ。
主要な連携は以下のようになると思う。
・CSVやXML、json 形式のテキストファイルによる連携
テキストファイルは全て文字コード変換が必要になる可能性がある。
・SOAP,REST など、Web-API によるサービス連携
SOAPの中身はXML,RESTの中身はjsonなので、標準規格の通りに作られていれば全て utf-8 を使用している。
しかし shift-jis の XML など規格外の作り方をしている場合があるので、要確認だ。
・DBMSのデータリンク機能によるDB直接連携
OracleなどのDBMSは他のサーバーのOracleのテーブルを直接SQLで参照更新する事ができる。この場合、接続先のキャラクターセットが同じか確認する必要がある。
異なるならキャラクターセットの変換が必要だ。
・専用ソフトによるレプリケーション連携
遠隔地にある複数のDBMSのデータや一部のテーブルを、常に同一の内容になるように更新を続けるレプリケーションソフトがある。
レプリケーション対象テーブルを更新すると連携先の同一レイアウトのテーブルが同様に更新される。
・ソケット・プロセス間通信によるアプリ連携
TCP/IPソケットで、他システムと通信するケースも珍しくない。
ソケットはどの文字コードを使用しても良いので、使用する文字コードは要確認だ。
また、同一筐体で稼働する他システムならパイプやキューなどプロセス間通信を使用して通信している可能性もある。こちらも文字コードを要確認である。
DBMSのキャラクターセット
DBMSの種類にもよるが、DBMSではshift-jisやeuc-jpの場合は、データ型にCHAR,VARCHAR2,CLOBを使用するのに対して、
utf-8 や utf-16 の場合はNCHAR,NVARCHAR2,NCLOBを使用するものが多い。
データリンクでSQLクエリーを書くとき注意。
システム内部のエンコーディング
開発言語やミドルウェアにもよるが、バックエンドやフロントエンドのエンコーディングは現在では、utf-8 で統一されていると思って良いと思う。
余程古い開発言語で無い限り、shift-jis でコードを書いている事はない。
但し、SQLは別である。キャラクターセットと同じ文字コードでコーディングしている可能性が高い。
余程古いシステムでない限り、システム内部のエンコーディングは utf-8 と考えて問題ないと思う。
もし旧システムがshift-jisでコーディングしていたら、Git,SVNなどソース管理の部分に注意が必要だ。
新システムは異なるソース管理にする必要がある。
バッチシステムのエンコーディング
旧バッチシステムがもし、WSH(VBScript)や、.BAT などで開発されていたら、間違いなくshift-jisを使用している。
これらは utf-8 を使用できない。
新システムで utf-8 を使用するならPowerShellなどでバッチを開発する事になる。
バッチで新旧連携するなら、PowerShell側(新システム)で文字コード変換が必要だ。
PowerShellはv6.2以上ならshift-jisも扱える。
もちろんUNICODEは扱える。
コマンドプロンプト(cmd)との連携
以前も書いたが、cmd は そこで使用できる dir,type,cd など標準コマンド全てで shift-jis しか使用できない。
.bat ファイルなどのスクリプトファイルも同様である。
utf-8 など Unicode には全く対応していない。
exe ファイルで開発したバッチが標準出力に utf-8 のテキストを出力しても文字化けして表示できない。
業務でコマンドプロンプトを使用する場合は、標準出力は shift-jis にする必要がある。
むろん標準入力も同様だ。
BOMの管理
他の旧システムなどが shift-jis で開発されており、新システム以降は utf-8 で開発する方針ならば、職場では shift-jis のテキストと utf-8 のテキストが混在する事になる。
ユーザーが両者を区別し、必要ならば自分で文字コードを変換する必要がある。
utf-8 で扱える文字コードには shift-jis では扱えない文字コードが沢山あるので、文字コードの変換が極力発生しないように業務設計する必要がある。
注意点として、Windows10 のメモ帳やvs-codeなどのテキストエディタで新規作成するテキストファイルは「BOMなしutf-8」のテキストファイルであるという事。
そして、Excel2016以降では「BOMなし」CSVは shift-jis と解釈され、「BOM有り」CSVは utf-8 と解釈される点だ。
業務で shift-jis と utf-8 を混在させるなら、「BOMなしテキストはshift-jis」「BOM有りテキストはutf-8」という運用ルールを定めるべきだと思う。
メモ帳やvs-codeは「BOM有りutf-8」を正しく認識し更新もできるので問題はない。
テキストの新規作成はユーザーにやらせずにシステムが行うようにすれば、「BOMなしutf-8」ファイルが業務用テキストファイルに発生することもない。
Excel2016以降なら「BOM有りutf-8」のCSVファイルを正しく読み書きできる。
「BOMなしテキストはshift-jis」
「BOM有りテキストはutf-8」
という運用ルールはユーザーにも周知徹底する必要がある。
当然、文字コードの違いについてユーザーに説明する必要がある。
ユーザーでもこの程度のIT知識がなければ今時ITシステムの運用などできない。
細かい事はユーザーの協力の下で「運用でカバー」しなければITシステムに金が掛かりすぎで現実的なシステム運用はできない。
テキストファイルとCSVファイル入出力
utf-8で運用する新システムからダウンロードするテキストファイルと、新システムへアップロードするテキストファイルも、先に説明した「BOMなしテキストはshift-jis」「BOM有りテキストはutf-8」の運用ルールに従う必要がある。
大半の企業は shift-jis で運用している旧システムが存在するはずで、その旧システムと新システムを並列運用することになる。
この場合、旧システムが出力したテキストファイルやCSVファイルを、新システムにアップロードする場合は、 shift-jis から utf-8 への変換が必要だ。
この変換事態はさほど問題ではない。
もし、自動で変換するなら新システム側にBOM判定で自動変換処理を加えるべきだろう。
逆に新システムが出力したテキストファイルやCSVファイルを、旧システムにアップロードする場合は、 utf-8 から shift-jis への変換が必要だ。
この変換は問題がある。
以前書いた記事「shift-jisでシステム開発するデメリット」に記載したように、 utf-8 で扱う文字の中には、 shift-jis では扱えない文字が沢山ある。
単純に utf-8 から shift-jis へ変換する処理を実施するだけでは済まないのだ。
shift-jis へ変換できない文字が現れた場合、例外処理を行う必要がある。
単純な例外処理ならエラー終了してユーザーに対処を任せる事になる。
もう少し凝った処理なら、日本語文字に限り、印刷標準字体や旧字体を対応する、常用漢字や新字体へ変換する事が考えられる。
中国・台湾・韓国の漢字なども同様の対処が考えられるが、変換できない文字も存在する。
中国の「产」などの簡体字は、日本語の「彦」「産」「諺」など、どの漢字に当てれば良いか分からない。
この場合はエラーにして対象漢字をエラーログなどに残す必要がある。
ユーザーにはエラーログを見て対処して貰うのでエラーログの参照機能も作らなければならない。
ログ出力
実行ログやエラーログなど出力する必要はあるはずだ。
この時、旧システムとの柵みで shift-jis で出力しなければならない場合もあると思う。
この点も基本設計の段階でルールを決めておく必要がある。
Excel入出力
CSVではなく、Excelの「xlsx」形式のファイルで直接出力する場合もあると思う。
また、VSTOなどの仕組みで直接、フロントエンドのExcelとシステムのAPIサービスが通信する場合もあると思う。
Excel2016以上であれば、これはむしろUNICODEの方が扱い安いと思う。
ただ、Excelの内部は utf-16LE なので utf-8 と変換が必要になるかも知れない。
UNICODE同志の変換は可能であり、.NET など主用な開発環境ではエンコードの変換は容易であるからさほど問題ないと思う。
旧Excelバージョンとの連携
旧Excelの内、2013以前のバージョンはshift-jisのCSVしか読めない。
古い「xls」形式のファイルではshift-jisしか扱えない。
Excel2013以前のバージョンを使用しているなら、新バージョンにアップグレードした方が良い。
これに対処するコストの方が高く付く。
Excel VBAとの連携
先に説明したが、Excel内部は utf-16LE を使用しているので、utf-8 は utf-16LE に変換してExcel VBAと連携する事になる。
.NET などを使用するとさほど難しくない。
旧データとの連携
旧データが shift-jis で作成されているなら、旧データを丸ごと utf-8 という事も考えられるが、現実的ではない。
テキストファイルの運用ルールと同様に「BOMなしテキストはshift-jis」「BOM有りテキストはutf-8」の運用ルールで運用すべきである。
テキストファイル以外のデータなら、DBMSならDBMS自身が判別できる。
それ以外の形式のデータなら、shift-jis と utf-8 を単純に識別できるルールを制定して共存する必要がある。
文字コードの変換と変換エラーへの対処
先に説明したが、文字コードの変換が出来ないケースがある。
変換できない場合はエラーログを残し、ユーザーにエラーログを見て貰って、手動で対処して貰う必要がある。
また、その機能を作る必要がある。
文字コード混在対応の処理は新システム側に実装する
shift-jis を使用する旧システムと utf-8 を使用する新システムを混在する場合、システムが対応しない文字コードのテキストファイルをアップロードするケースに対応しなければならない。
utf-8 を使用する新システムに shift-jis のCSVファイルをアップロードしたり、shift-jis を使用する旧システムに utf-8 のCSVファイルをアップロードするケースの事である。
この場合、旧システムの入力処理で utf-8 入力に対処する方法と、新システムの入力処理で shift-jis に対処する方法が考えられる。
理想を言えば、両方とも行うべきだと思う。
しかし、現実にはシステムの数が多かったりして、全てのシステムの改修は出来ないケースが多数派だと思う。
よって、どちらか一方だけの対処で済ます事にすると思う。
私は文字コード混在への対処は utf-8 を使用する新システム側で行うべきだと思う。
これから業務で utf-8 を標準文字コードとするのだから、どこでも utf-8 が使用できるように、旧システムの入力処理で utf-8 入力に対処するべきだと思うかも知れない。
旧システムは既に開発者がいないかも知れない。
旧システムの数が多いと予算人員工数的にも改修は不可能である場合がある。
全ての旧システムを改修するのは無理である。
単純に utf-8 のテキストがアップロードされた時にエラーにするだけでも難しいと思う。
現実的に予算人員工数的にも改修可能な、新システムの入力処理で shift-jis に対処する方法を選択すべきである。
新システムに shift-jis のテキストがアップロードされたらBOMの有無で判断して、utf-8 に変換する処理を組み込む。
新システムから旧システムへテキストデータ連係(送信)する場合は、そこだけ shift-jis テキストで出力する。
「shift-jis CSV出力」「utf-8 CSV出力」というように二つのボタンを画面に用意する対処も必要かもしれない。
テキストファイルによる連携、Web-API によるサービス連携、データリンク機能によるDB直接連携、ソケット通信によるアプリ連携の全てで、同様の対処を行うべきだ。
Web-APIなら旧システムと連携する専用APIを作成し、shift-jis で連携する。
新システム内部で utf-8 との変換を行う。
ソケット通信も同様である。
データリンク機能によるDB直接連携の場合は、新システム側に旧システムとのデータリンク専用のテーブルを用意して、旧システムとは shift-jis でデータ連係する。
データリンク専用のテーブルを新システム側で読むときは、別のutf-8テーブルに文字コード変換してデータコピーして読み書きする。
レプリケーションも同様である。
この方法なら utf-8 と shift-jis の文字コード変換エラーは全て新システム内で発生する。エラーログも新システム内にだけ用意すれば良い。
文字コード変換処理を一元化できる。
旧システムの改修も必要ない。
インターフェイスは二つ用意しておく
新システムに作り込む、旧システムとの連係機能は shift-jis用と utf-8用の二つを用意しておく。
機能は両方同じにしておく。
なぜかと言えば、
将来旧システムはマイグレーションされ、utf-8で開発される。
その時、新システムの連係機能が shift-jis にしか対応していないと、マイグレーションしたシステムは内部で utf-8 を使用しているのに 連携処理だけ shift-jis に対応しなければならない。
これはナンセンスだ。
初めから全てのシステムが utf-8 にマイグレーションされる事を想定して新システムを開発すべきだ。
同じ機能を shift-jis 用と utf-8 の二つ用意するなら設計もテストも同じで同時に開発できる。
工数はさほど膨らまないはずだ。
文字コード変換ルールを定義する
もし可能であれば utf-8 で使用できて shift-jis で使用できない文字の変換ルールも定めておいた方が良いと思う。
旧字は新字に置き換え可能である。
印刷標準字体も常用漢字に置き換え可能である。
台湾の繁体字も日本語の新字に置き換え可能である。
韓国の漢字も新字に置き換え可能である。
中国の簡体字は置き換えられないと思う。エラーにすべきだろう。
これらは予め変換ルールをDBテーブルに置いておき、 utf-8 から shift-jis に文字コード変換する時に文字を置き換えてしまう。
全部、エラーにするより、スムーズに業務が回る。
システムの utf-8 化はいずれ必要になる
現在のところ、過去のシステム及びデータ資産との柵みで、 shift-jis テキストでの入出力を行っている業務システムは多いと思う。
会計アプリや官公庁とのデータのやり取りは、shift-jis テキスト(CSV含む)が多いので、今のところshift-jisを使用した方が良い場合もある。
ただ、DBMSやシステム内部で使用する文字コードはUNICODE(utf-8)になっている。
中国・台湾・韓国・ベトナムなど海外とデータのやり取りをする機会も増えてくる。
旧字体など常用漢字以外の漢字の使用機会も増えていく。
この先、shift-jis だけで業務を回し続けていく事は不可能だと思う。
だから、いずれ業務の現場はshift-jisテキスト(CSV含む)から、UNICODE(utf-8)テキストへ移行する必要がある。
それが何時になるかわ現場の都合によるが、二千年問題のように現場のITエンジニアは問題の存在を知っているのに、その上司の経営者や管理職は問題の大きさを認識していないという状態と、似た状態になっている。
経営者や管理職は業務システムの文字コード問題が存在する事を早く自覚すべきでだろう。
shift-jisテキストから、UNICODE(utf-8)テキストへ移行する時は、両方のデータが混在する事が避けられない。
現場ユーザーレベルで二つの文字コードに対処する必要がある。
ユーザーいつまでもITオンチのままでいて良いわけではない。