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

CSVデータとは、カンマと改行2種類の区切りコードを用いて2次元の表形式で保持するものです。
サンプルは、カンマ毎を1次元目、改行毎を2次元目の要素として配列変数に代入する例です。
コレを参考に便利で汎用的なモジュールを作成してみてはいかがでしょうか?
HSP2では、標準で配列の要素数を取得する命令が用意されていないので、
内部でコチラgetdiminfo命令を使用しています。サンプルのように先に定義しなければ使用できません。
逆の「配列データをCSVデータに変換するサンプル」はコチラをご覧ください。
	

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

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

 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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#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 csvtoarray val, val
	mref sv, 56 : mref gv, 25
	i = 0, 0, 0                                     // 2次元目の要素, 開始位置, 行区切り位置
	ckugiri = "," : rkugiri = "\n"                  // 1次元目区切り文字, 2次元目区切り文字
	strlen len.0, gv
	strlen len.1, ckugiri
	strlen len.2, rkugiri
	getdiminfo sv, 0 : size.0 = stat                 // 1要素のバッファサイズ
	getdiminfo sv, 1 : size.1 = stat                 // 1次元目の要素数
	getdiminfo sv, 2 : size.2 = stat                 // 2次元目の要素数
	sdim rdat, size.0 * size.1 + 1
	repeat
		// 要素数よりも大きい分は代入しない
		if cnt >= size.2 : break
		// 1行分のデータ抽出
		instr i.2, gv, rkugiri, i.1
		if i.2 = -1 {
			strmid rdat, gv, i.1, len.0
			if rdat = "" : break
		} else {
			strmid rdat, gv, i.1, i.2
		}
		// 1行の長さ取得
		strlen len.3, rdat
		i.3 = 0, 0 // 1行内の開始位置, カンマ区切り位置
		repeat
			// 要素数よりも大きい分は代入しない
			if cnt >= size.1 : break
			// カンマ毎のデータ抽出
			instr i.4, rdat, ckugiri, i.3
			if i.3 + i.4 <= i.3 {
			if len.3 - 1 > i.3 {
			    if len.3 - i.4 >= size {
			      strmid sv.cnt.i, rdat, i.3, size       // 配列の要素サイズ以下なら全て代入
			    } else {
			      strmid sv.cnt.i, rdat, i.3, len.3 - 1 // 配列の要素より大きい分は代入しない
			    }
			  }
			break
			}
			if i.4 >= size {
			  strmid sv.cnt.i, rdat, i.3, size           // 配列の要素サイズ以下なら全て代入
			} else {
			  strmid sv.cnt.i, rdat, i.3, i.4           // 配列の要素より大きい分は代入しない
			}
			i.3 += i.4 + len.1
		loop
		i.0++ : i.1 += len.3 + len.2
	loop
	return
#global

	sdim ary, 10, 7, 4
	sdim csv, 200
	sdim genre, 5, 4
	genre = "OS", "衣服", "食べ物", "国"
	csv = {"
		3.1,95,98,Me,2000,XP,Vista
		Tシャツ,スーツ,ドレス
		パン,野菜,肉,魚,米
		日本,アメリカ,ロシア,中国
	"}
	csvtoarray ary, csv // CSVデータを配列に格納
	repeat 7
		pos cnt * 80 + 100, 10 : mes cnt
	loop
	repeat 4
		row = cnt
		pos 10, row * 30 + 50 : mes "<" + genre.row + ">"
		repeat 7
			pos cnt * 80 + 100, row * 30 + 50 : mes ary.cnt.row
		loop
	loop
	stop

csvtoarray 設定先配列変数, 取得元変数
設定先配列変数取得元変数テキストのCSVデータを2次元配列の各要素にセットする。
取得元変数配列にセットしたいCSV形式の文字列型変数を指定する。

 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
#module
#deffunc csvtoarray array sv, var gv, local i, local ckugiri, local rkugiri, local rdat
	i = 0, 0 // 配列2次元目の要素番号, 全体の取得開始位置
	ckugiri = "," : rkugiri = "\n"
	repeat
		// 1行分のデータ抽出
		if instr(gv, i.1, rkugiri) = -1 {
			rdat = strmid(gv, i.1, strlen(gv))
			if rdat = "" : break
		} else {
			rdat = strmid(gv, i.1, instr(gv, i.1, rkugiri))
		}
		// カンマ毎のデータ抽出
		i.2 = 0 // 1行内の取得開始位置
		repeat
			if i.2 + instr(rdat, i.2, ckugiri) <= i.2 {
			if strlen(rdat) - 1 > i.2 : sv.cnt.i = strmid(rdat, i.2, strlen(rdat))
			break
			}
			sv.cnt.i = strmid(rdat, i.2, instr(rdat, i.2, ckugiri))
			i.2 += instr(rdat, i.2, ckugiri) + strlen(ckugiri)
		loop
		i.0++ : i.1 += strlen(rdat) + strlen(rkugiri)
	loop
	return
#global

	sdim ary, 10, 5, 4
	sdim csv, 200
	sdim genre, 5, 4
	genre = "果物", "乗り物", "都市", "家電"
	csv = {"
		りんご,バナナ,みかん,ぶどう,メロン
		電車,バス,タクシー
		大阪,博多,東京,札幌
		テレビ,デジカメ,冷蔵庫,クーラー,パソコン
	"}
	csvtoarray ary, csv // CSVデータを配列に格納
	repeat length(ary)
		pos cnt * 100 + 120, 10 : mes cnt
	loop
	repeat length2(ary)
		row = cnt
		pos 10, row * 30 + 50 : mes "<" + genre.row + ">"
		repeat length(ary)
			pos cnt * 100 + 100, row * 30 + 50 : mes ary.cnt.row
		loop
	loop