PowerObject 配列に格納された値が、最後に格納した構造体とすべて同じ値になる

バグ情報

PowerObject 配列に格納された内容が、最後に格納した構造体と同じ値としてセットされてしまう事象が報告されています。

Bug ID 6606
Product PowerBuilder EN/JP
ステータス [JP]PowerBuilder 2019 R3 日本語版 GA (Build 2722) で修正済
発生バージョン EN 12.6以前 2017 (R2) 2017 (R3) 2019
JP 12.6以前 2017 (R2) 2017 (R3) 2019

:発生バージョン    :解決済み、未発生    :未確認

(2017 以外のバージョンについてはリリースされている最新リビジョンでの状況です)

詳細

構造体の中で定義している PowerObject 型の配列に対し、継承可能なオブジェクト (ウィンドウ、ユーザーオブジェクト、メニュー) の子孫に記述した処理で、別の構造体を一つの変数として値を変えながら配列に格納する場合、PowerObject 型の配列に格納されたすべての値が最後に格納した構造体と同じ値になってしまいます。たとえば、以下のようなケースで発生します。

構造体 : str_element

global type str_element from structure
	string		sample_string
	long		sample_long
end type

構造体 : str_parm

global type str_parm from structure
	powerobject		str_object[]
end type

スクリプト

str_element lstr_ent
str_parm lstr_out
long index

for index = 1 to 5
	
	lstr_ent.sample_string = "テスト名" + string(index)
	lstr_ent.sample_long = index
	
	lstr_out.str_object[index] = lstr_ent
	
next

このような場合、PowerBuilder 2017 R2 までは構造体 str_element の sample_string には、“テスト1” から “テスト5” が、sample_long には “1” から “5” が格納されていましたが、PowerBuilder 2017 R3 以降のバージョンでは sample_string には、すべて “テスト5” が、sample_long にはすべて “5” が格納されます。

回避策

構造体に格納する前に、一度 PowerObject 型の変数を経由することで問題を回避することができます。 たとえば、以下のようにグローバル関数を使用して、構造体に PowerObject を渡します。

グローバル関数 : gf_pass_structure

global subroutine gf_pass_structure (ref powerobject apo_source, powerobject apo_target);

apo_source = apo_target

end subroutine

スクリプト

//lstr_out.ent_object[index] = lstr_ent
gf_pass_structure(ref lstr_out.str_object[index], lstr_ent)
バグ情報 一覧を見る
PowerBuilder マイグレーション
PowerBuilder 2019 R3 日本語版リリース 紹介動画