デジタル推進課

KNIME・Excel Macro・Power Automateなど日々の業務で使用できる自動化ツールを中心に書き綴ります

KNIME - 固定長のファイルを読み込む fixed length input ~Java Snippet~

 

f:id:makkynm:20201220101041p:plain

 

はじめに

 こんにちは、まっきーです。今回は書いていたと思って書いていなかった固定長のデータを、Digit数で読み込む方法を解説したいと思います。

 

前回は固定長ではなくて文字数で区切る方法を解説しました。そして前回、全角と半角が混じっている場合はうまく区切れないですね!ということだけ投げてじゃあその場合どうすんの?というところをカバーしていませんでした。

今回はきちんと半角と全角が混じっているファイルでも区切れる方法を解説します。

degitalization.hatenablog.jpJ

※この方法Macでは動きませんでした。デフォルトの文字コードの違いからかもしれません。原因分かればまた記事書こうと思います。 

 

 今回のテーマ ~Java Snippet~

 Java Snippet Nodeを使って固定長のデータを複数コラムに分割していきます。

f:id:makkynm:20201127114517p:plain

 今回のテーマ ~Java Snippet~

JavaのNodeを初めてみる方は、まずは下記の記事を読んでみてください。

degitalization.hatenablog.jp

 

 

 固定長のファイルとは?

そもそも固定長ファイルという言葉をご存知でしょうか。コトバンクによると、固定長は下記の定義になっています。

長さ・桁数・文字数データの大きさなどが定められていること。特に、コンピューターで、レコードファイルを構成する単位)の長さが一定である形式を指す。⇔可変長

引用:

固定長とは - コトバンク

 

固定長というのは、長さが決まっているということです。あらかじめ決めた区切り位置のルールに沿って、それぞれ値を入れていくイメージです。

テキストファイルには、いくつかの区切り方があったと思います。カンマ区切り、タブ区切り、スペース区切り等です。この固定長ファイルは、この区切りが長さで決められているものです。

今回は下のような固定長ファイルを用意してみました。上の方に半角スペースを1digitとしたメモリが振られているので、すこし分かるかもしれませんが、あらかじめ決めておいたDigit数から各値がスタートするイメージです。

f:id:makkynm:20201127140137p:plain

固定長ファイルの例

 

固定長ファイルはかなり一般的なので、Nodeとして用意されていてもおかしくないのですが、どうやらまだないみたいです。

fixed length input - KNIME Analytics Platform - KNIME Community Forum

古い基幹システムからバッチ処理で吐き出されるファイルの多くはこの固定長ファイルとなっているので、かなりビジネスケースとしては大きいと思うのですが、、、

ぜひ作っていただきたいですね。

 

覚えてほしいこと

  • new String(sbyte, 開始digit数, Digit長さ);
  • 半角は1digit, 全角は2digit

日本語は全角なので、英語の2倍スペースを取ってます。

f:id:makkynm:20201127141058p:plain

全角は2digit分

 

やりたいこと

下のような固定長のデータを読み込んでいきます。今回はスペースが半角となっているため、文字数で区切る方法(Cell splitterやFixed width file reader)は使用できません。

f:id:makkynm:20201127140137p:plain

固定長ファイル

 

固定長ファイルの読み込み方

Workflow

Workflowは下のようになります。

まず、File Readerでファイルを1つのコラム、複数の行として読み込みます。

次に今回解説するJava Snippetで、Digit数でコラムを区切っていきます。

最後に、元々のコラムを削除して、Headerを挿入したら完成です。

f:id:makkynm:20201127114517p:plain

Workflow - Java Snippet 固定長ファイル

Step1 - File ReaderのConfigure - 1つのコラムとして取り込む

まずは、File Readerについてです。Column delimiterをnoneにすることにより、1つのコラムとして取り込むことができます。

degitalization.hatenablog.jp

 

f:id:makkynm:20201127130954p:plain

File Reader Configuration - 1つのコラムとして取り込む

MACの場合は、DefaultのCharacter decodingが、”UTF-8”だと思うので、user definedから、正しく読めるようにShift-JISを指定しました。

f:id:makkynm:20201127145202p:plain

decodingを指定

Step2 - Java Snippet Nodeで、Digit数によってコラムを分割する

ここが今回のメインの部分、Java Snippet NodeでDigit数を元にコラムを分割する部分です。文字列を一度、バイト配列に変換して、もう一度文字列に戻すという作業を行っています。

Charsetクラスの追加 - system imports

まず、String型をByte型という方に変換する際に使うクラスをImportします。文字コードを指定する際に使用します。

System importsの下にコピペしてみてください。このクラス、使わなくても変換出来きるのですが、一応Importの練習のために入れておきます。

f:id:makkynm:20201127141502p:plain

クラスを追加
import java.nio.charset.Charset;

 

String型からByte型の変換 - expression 

まずは、String 型をByte型に変換します。これは呪文だと思ってください。

これで、文字列をShift_JIS文字コードに変換した結果を、「sbyte」という変数に格納していきます。この、「c_Col0」の部分は、File Readerで取り込んだコラムになります。また、"Shift_JIS"の部分でEncodingを指定しています。「Charset.forName("Shift_JIS")」の部分はなくても動いたりします。OSが変わらない前提です。

 

byte[] sbyte = c_Col0.getBytes(Charset.forName("Shift_JIS"));

 

Byte型からString型の変換 - expression

 次にByte型からString型に変換していきます。下のようにOutputコラムを作った後に、開始位置と長さを書いていきます。

Output Column = new String(sbyte, 開始digit数, Digit長さ);

Outputコラムの名前はひとまず、Col1、Col2というようにしてみました。

// byte型からString型に変換
// String(sbyte, 開始digit位置, 文字長さ)
out_Col1 = new String(sbyte,0,10);
out_Col2 = new String(sbyte,10,10);
out_Col3 = new String(sbyte,20,9);
out_Col4 = new String(sbyte,29,4);
out_Col5 = new String(sbyte,33,8);
out_Col6 = new String(sbyte,41,8);
out_Col7 = new String(sbyte,49,8);
out_Col8 = new String(sbyte,57,8);

f:id:makkynm:20201127141647p:plain

固定長を分割する

 

f:id:makkynm:20201127140137p:plain

元ファイル

 

Confirm - before after 

実行すると、このように元コラムを元に複数コラムに分割できていることが分かります。

f:id:makkynm:20201128130150p:plain

Confirm - before after - Java Snippet 固定長分割

 

Step3 - 不要コラムを削除

ここまでくれば、もうほとんど終わったようなものです。まずは最初に取り込んだコラムが不要になったので削除します。

degitalization.hatenablog.jp

f:id:makkynm:20201128130436p:plain

Configure - Column Filter

Step4 - コラム Headerを挿入する

さて、最後にHeaderを挿入していきます。方法は下記の記事で解説した通りです。

degitalization.hatenablog.jp

Header行とデータ行の分割

まずは、全体のテーブルから1行目だけを分割して、コラムヘッダーの行と、データの行を分割していきます。

f:id:makkynm:20201128130739p:plain

Header行とデータ行を分割
コラムヘッダの挿入

Transposeで、Headerの行を横から縦に変換していきます。すると、Insert Column HeaderでLook upする形にすることができます。

f:id:makkynm:20201128130925p:plain

Configure - Insert Column Header

 

最終Output 

これできれいに固定長を KNIMEに取り込むことができました!

f:id:makkynm:20201128131206p:plain

最終Output

 

 

 ちょっと一言

 Javaで文字列・バイト配列変換を行うときに使用するクラスについて

下記の記事によると、Shift-JISはStandardCharsetsクラスで用意されていないようなので、Charset.forNameを使用しています。

Charset.forNameでUnsupportedEncodingExceptionを回避する - Qiita

また、GetBytesにCharsetを渡せるのはJava6以降のようです。

Macでは文字化けしてしまったので、文字コード変換についての記事をいくつか探しましたが、よくわかりませんでした、、、

もしMacでできた方いたら教えていただきたいです。

 

Digit数を数えるためのおすすめテキストエディタ紹介

Digit数を数えていくの大変ですよね。テキストエディタを使えばDigit数を数える補助をしてくれます。簡単なテキストエディタで全然構わないです。

私が今回使っていたテキストエディタTerapadというものです。下にメモリがついている簡単なテキストエディタをいくつか紹介しておきます。

Digit数を数えるためだけなので、メモリがついていてなおかつ動作の軽いソフトという基準で選んでいます。

無料、メモリあり、動作も軽いです。

TeraPad 公式ダウンロードサイト

無料、メモリあり、動作も軽いです。

サクラエディタ

メモリあり、動作も軽いです。有料ですが、無料化の方法が公開されています笑

研究室時代お世話になってました。本来有料エディタなので、機能が豊富です。

秀まるおのホームページ(サイトー企画)-秀丸エディタ

Ctrl + Shift + マウスの右ボタンを押しながらしながら「はい」をクリック

秀丸エディタのダイアログを表示させなくする方法 | 覚え書き.com

 

 

おわりに

きちんと動いたでしょうか。正直、この方法はしょうがなく使っている節があるので、もっといいやり方があれば知りたいです。また、この方法、デフォルトの文字コードの設定の問題か、MACでは動きませんでした。MACでどうやるのか、気になります。

もしご存知の方いたら教えていただけると大変嬉しいです。

基幹システムのような古くからあるシステムから自動的に吐き出されるファイルの多くが固定長ファイルだと思います。KNIMEの方々、ぜひ、OSに依存しないようなNode作っていただきたいです!(願望)

海外は全角があまりないので、問題にならないのかもしれませんね、、、ファイルが全て半角や全角で統一されていれば、文字数で区切れるFixed width file readerなどがあるので問題なく取り込まれると思います。

上級編ということで少し省略気味に書いていってます。ここ分からないというところがあれば指摘いいただけれ場と思います。ではまた!

 

 

少しの応援が大変励みになります。

まっきーにOFUSEする

f:id:makkynm:20201219150553p:plain

余談 

ブラックフライデーですね! 皆さん買い物捗っていますか?私はまだ買うものが思いつかず苦労しています。ちょっとよく分からないですが、自分の買うものリスト、買ったものリスト、共有しておきますね。

¥20,000 (税込) 以上買い物すれば、ポイントバックがあるみたいです。これを機に大きな買い物もありです、、、

 

生活必需品系

ひとまず生活必需品は買い溜めできますね!

マスク

この前洗えるマスクを購入したのですが、かなり良かったので共有します!触り心地が最高でした。

毎日使い捨てマスクはちょっと経済的にも痛かったので非常に満足でした。 

 食器用洗剤

つい昨日切れたのでちょうどよかったです。10回分もあれば当分困りません。

除菌ジョイ コンパクト 食器用洗剤 詰め替え ジャンボ 1330mL

除菌ジョイ コンパクト 食器用洗剤 詰め替え ジャンボ 1330mL

  • 発売日: 2020/03/22
  • メディア: ヘルスケア&ケア用品
 

シャンプー

 シャンプーもこんだけあったら余裕で持ちます。

 

 ボディーソープ

ボディーソープもこんだけあったら当分買わなくていいです笑

 

洗濯洗剤

ジェルボール楽ですよね!

 

在宅勤務用品

在宅勤務の環境整えると、仕事めっちゃ捗ります。

ディスプレイ

 ディスプレイは必須ですよね。2画面使うと作業効率が全然違います。

 

ディスプレイアーム

 ディスプレイを上下で2画面使うとほんと便利です。

 

キーボード

ワイアレスキーボードもいいですよね。大きなモニタがメインになるので作業しやすくなります。 

 

 

参考リンク