〜 スクリプト 〜
二次元配列をCSVデータに変換

CSVデータとは、カンマと改行2種類の区切りコードを用いて2次元の表形式で保持するものです。
配列1次元目の各要素をカンマで区切り、2次元目を改行で区切る例を下記のサンプルで示しています。
取得元の配列要素数を知る必要があるため、コチラgetdiminfo命令を使用しています。
また、設定先の変数サイズよりも、取得元配列の全要素と区切り文字を含む合計サイズの方が大きい場合に、
HSP2側サンプルのモジュールがエラーとならないようチェックを掛け、溢れ分は無視しています。
HSP3側サンプルは、溢れた場合に自動拡張する形を取っています。
HSP2同様にチェックを掛けて溢れ分を代入しないようにも作れますが、ここのチェックは、
溢れたデータを代入させないことではなく、意図しない動作や問題が起こる可能性を事前に防ぐ為です。
自動拡張する作りとしたのは、HSP側で溢れても問題ない形になっているにもかかわらず、
データがあっても溢れたからといって代入せずに処理を正常終了するのは、ナンセンスだと思ったからです。
ご自分で使用する場合はチェックや自動拡張をせずとも完全に代入できるよう、
HSP2・HSP3問わず、設定先配列のサイズを大きく確保しておくほうがイイでしょう。
逆の「CSVデータを配列データに変換するサンプル」はコチラをご覧ください。
	

getdiminfo 変数, 次元
変数指定変数、指定次元のサイズがstatにセットされる。
次元1次元目を0として、取得する次元を0〜3のいずれかで指定する。

arraytocsv 設定先変数, 取得元配列変数
設定先変数2次元配列変数の各要素をCSV形式にしてセットする。
内部でgetdiminfo命令を使用している為、
arraytocsv命令の前にgetdiminfo命令を定義すること!
取得元配列変数CSV形式で変数にセットしたい文字列型の2次元配列変数を指定する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#module
#deffunc getdiminfo val, int
	mref pval, 1024 : mref dnum, 1
	mref stt, 64
	stt = dnum + 2
	stt = pval.stt
	if (pval & $FFFF = 2) && (dnum = 0) : stt = stt * 4
	return

#deffunc arraytocsv val, val
	mref sv, 24 : mref gv, 57
	getdiminfo sv, 0 : size.0 = stat // 設定先変数のバッファサイズ
	getdiminfo gv, 0 : size.1 = stat // 取得元配列1次元目のバッファサイズ
	getdiminfo gv, 1 : size.2 = stat // 取得元配列1次元目の要素数
	getdiminfo gv, 2 : size.3 = stat // 取得元配列2次元目の要素数
	sdim tmpdat, size.1 + 1
	ckugiri = "," : rkugiri = "\n"  // 1次元目区切り文字, 2次元目区切り文字
	strlen len.0, ckugiri
	strlen len.1, rkugiri
	repeat size.3
		i = cnt
		strlen len.2, sv
		if i ! 0 & (len.1 + len.2 + 1 < size.0) : sv += rkugiri
		repeat size.2
			strlen len.2, sv
			if cnt ! 0 & (len.1 + len.2 + 1 < size.0) : sv += ckugiri
			strlen len.2, sv
			strlen len.3, gv.cnt.i
			if len.2 + len.3 + 1 < size.0 {
			  sv += gv.cnt.i
			} else {
			  strmid tmpdat, gv.cnt.i, , size.0 - len.2 - 1
			  sv += tmpdat
			  break
			}
		loop
	loop
	return
#global

	genrenum = 3
	sdim genre, 12, genrenum
	sdim ary, 16, 5, genrenum
	sdim csv, 100
	genre = "メーカー", "Color", "三種の神器"
	ary.0.0 = "トヨタ", "ニッサン", "ホンダ", "スズキ"
	ary.0.1 = "Red", "Green", "Blue", "White", "Black"
	ary.0.2 = "草薙の剣", "八尺瓊の勾玉", "八咫の鏡"
	arraytocsv csv, ary // 配列データをCSV変数に格納
	// CSVデータを1行毎取り出して表示する
	notesel csv
	repeat genrenum
		noteget current, cnt
		pos  10, cnt * 30 + 10 : mes genre.cnt
		pos 100, cnt * 30 + 10 : mes current
	loop
	stop

arraytocsv 設定先変数, 取得元配列変数
設定先変数2次元配列変数の各要素をCSV形式にしてセットする。
取得元配列変数CSV形式で変数にセットしたい文字列型の2次元配列変数を指定する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#module
#deffunc arraytocsv var sv, array gv, local i, local ckugiri, local rkugiri
	ckugiri = "," : rkugiri = "\n" // 1次元目区切り文字, 2次元目区切り文字
	repeat length2(gv)
		i = cnt
		if i : sv += rkugiri
		repeat length(gv)
			if cnt : sv += ckugiri
			sv += gv.cnt.i
		loop
	loop
	return
#global

	sdim genre, 12, 3
	sdim ary, 16, 5, 3
	sdim csv, 100
	genre = "メーカー", "Color", "三種の神器"
	ary.0.0 = "トヨタ", "ニッサン", "ホンダ", "スズキ"
	ary.0.1 = "Red", "Green", "Blue", "White", "Black"
	ary.0.2 = "草薙の剣", "八尺瓊の勾玉", "八咫の鏡"
	arraytocsv csv, ary // 配列データをCSV変数に格納
	// CSVデータを1行毎取り出して表示する
	notesel csv
	repeat notemax
		noteget current, cnt
		pos  10, cnt * 30 + 10 : mes genre.cnt
		pos 100, cnt * 30 + 10 : mes current
	loop