トップ回答者
クリスタルレポートでの全半角判定、または文字列のバイト数取得方法について

質問
-
環境
OS = Win7 Pro
DB = SQL Server 2014
開発環境 = Visual Studio 2015 Pro
クリスタルレポートOEM版のバージョン = CRforVS_13_0_21
いつもお世話になっております。状況
・クリスタルレポートにて、幅が100バイト分、5行程度表示できるオブジェクトを配置しています。
・表示したい文字列はDBから取得しています。
・データは、全半角混在しており、「数字:(コロン)全半角混在文字列」の法則で、カンマ区切りで登録されています。やろうとしている事
100バイトに到達して、クリスタルレポートで中途半端な文字で自動改行される前に、
文字列のバイト数を計算して、きりの良い場所で改行文字を挿入しようとしております。ご教示いただきたい事
クリスタルレポートの書式エディタに記載する為、
クリスタル構文での全角、半角判定やバイトの取得方法をご教示下さい。
以上、何卒宜しくお願い申し上げます。
回答
-
自分なら逆に考えて、改行してもいい全ての箇所にゼロ幅スペース(U+200B)を挿入しますね。
そうしておけばテキストオブジェクトがどんな幅に指定されていても自動改行が処理してくれますから。
それでも望むような状態にならないなら限界として諦めますが。切りの良い場所を判定するロジックを作れるなら、挿入位置をしていすることは簡単でしょう。
#NBSPはだめっぽい?
個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
- 回答としてマーク kong0214 2017年12月26日 7:10
-
直接の回答ではありませんが、実現の方向性として、一旦プログラムでデータを受け取り、そこで加工してデータテーブルを作成してそこに入れ、それをクリスタルレポートで表示するのではダメなのでしょうか? この方法だといかようにもなります。
この先、このような案件に出会った際にも、このような方法を取っていれば、それほど悩まずに実現できる可能性が高くなると思います。
以前、QRコードの表示の件で質問されていましたが、QRコードのイメージを作成し、データテーブルに入れれば、同じように表示できます。ちなみに、100バイト分の幅を取ったとしても必ず100バイトで改行されるわけではありません。クリスタルレポートが独自のロジックで改行してしまいます。USP10.DLLのバージョンが関係している情報がありましたが、結局、私は諦めました。
それとも、現在は改善されているのでしょうか?★良い回答には回答済みマークを付けよう! MVP - .NET http://d.hatena.ne.jp/trapemiya/
- 回答としてマーク kong0214 2017年12月26日 7:10
すべての返信
-
直接の回答ではありませんが、実現の方向性として、一旦プログラムでデータを受け取り、そこで加工してデータテーブルを作成してそこに入れ、それをクリスタルレポートで表示するのではダメなのでしょうか? この方法だといかようにもなります。
この先、このような案件に出会った際にも、このような方法を取っていれば、それほど悩まずに実現できる可能性が高くなると思います。
以前、QRコードの表示の件で質問されていましたが、QRコードのイメージを作成し、データテーブルに入れれば、同じように表示できます。ちなみに、100バイト分の幅を取ったとしても必ず100バイトで改行されるわけではありません。クリスタルレポートが独自のロジックで改行してしまいます。USP10.DLLのバージョンが関係している情報がありましたが、結局、私は諦めました。
それとも、現在は改善されているのでしょうか?★良い回答には回答済みマークを付けよう! MVP - .NET http://d.hatena.ne.jp/trapemiya/
- 回答としてマーク kong0214 2017年12月26日 7:10
-
自分なら逆に考えて、改行してもいい全ての箇所にゼロ幅スペース(U+200B)を挿入しますね。
そうしておけばテキストオブジェクトがどんな幅に指定されていても自動改行が処理してくれますから。
それでも望むような状態にならないなら限界として諦めますが。切りの良い場所を判定するロジックを作れるなら、挿入位置をしていすることは簡単でしょう。
#NBSPはだめっぽい?
個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
- 回答としてマーク kong0214 2017年12月26日 7:10
-
いつもお世話になっております。
下記のプログラムをクリスタルレポートのカスタム関数として
作成し、問題を解決致しましたので御報告致します。//maxLength = 最大文字列幅
//paramData = カンマ区切りの文字列データ
Function (Numbervar maxLength,Stringvar paramData)
(
local Numbervar targetByteTotal := 0;
local Numbervar i := 0;
local Stringvar returnData;//カンマ区切りにした場合の配列数を取得
local Numbervar cnt := Count(Split(paramData,","));//配列は「1」から始まる
For i := 1 to cnt do
(
local Numbervar j :=1;
local Numbervar getAsc :=0;
local Numbervar targetByte := 0;
local Numbervar targetLength := 0;
local Stringvar temp := "";
local Stringvar target = "";//文字列数を取得
targetLength := Length(Split(paramData,",")[i]);//対象文字列
target := Split(paramData,",")[i];//1文字目~最後まで
For j := 1 to targetLength do
(//1文字ずつ取得
temp := Mid(target,j,1);//文字コード取得
getAsc := Asc(temp);if getAsc < 256 and getAsc > -1 then
(
//0~255の範囲内であれば、1バイト文字
targetByte := targetByte + 1;
)
else
(
//0~255の範囲内でなければ、2バイト文字
targetByte := targetByte + 2;
)
);//文字列数 + 「カンマ」分追加
targetByteTotal := targetByteTotal + targetByte + 1;//オブジェクトの表示文字幅数を超えているか?
if targetByteTotal > maxLength then
(
//表示文字列幅を超えている場合、改行文字を間に挟む
returnData := returnData & Chr(10) & Chr(13) & target & ",";//改行文字挿入後に新たに追加した文字列数とカンマ一文字分を格納
targetByteTotal := targetByte + 1;
)
else
(
//表示文字列幅を超えていない場合、追加
returnData := returnData & target & ",";//何故か数字を格納する処理を入れないとコンパイル(保存)ができない為、意味はないが、記載
targetByteTotal := targetByteTotal;
)
);
//最後のカンマを除いて返す
returnData := Mid(returnData,1,length(returnData) -1);
)