|
|
2017/12/16(Sat) 15:35:08|NO.82038
教えて頂きたいです。
CSVファイルのC3、D3、E3、E4の値を読込み、
読込んだ値を新しいファイルのtest1.csvに書き込みたいです。
任意の場所の値を読込み書き出す方法を教えてください。
初心者故全く分からないです、よろしくお願いします。
|
|
2017/12/16(Sat) 18:10:43|NO.82039
C3、D3、E3、E4と言うのはExcelで開いたときのセルを言ってますか?
hspインストールフォルダの以下のサンプルが参考になるかと思います。
C:\hsp35\sample\hspda\csvnote.hsp
|
|
2017/12/16(Sat) 18:20:40|NO.82040
あー、hspdaにはcsv関係の命令があるのか。
以下、標準命令だけでcsvの読み書きを試みていますが、
hspdaの方がわかりやすいならそちらを利用してください。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
たとえば、「test0.csv」という以下のようなcsvファイルがあったとします。
0,1,2,3,4
5,6,7,8,9
10,11,12,13,14
15,16,17,18,19
ここから、お目当てのセルにある数値を抜き出すことになります。
・csvファイルは、各行のデータがコンマ(,)で区切られたテキストファイルである。
・テキストファイルの読み書きにはnote系命令(notesel、noteload、noteget、notesave、noteunsel)を使えばよい。
・特定の文字(ここでは",")で区切られた文字列を分割するには、splitを使えばよい
以上を踏まえた上で、csvファイルを元に2次元配列を作る命令と、
2次元配列の内容をcsvに書き出す命令を作ってみました。
#module
#deffunc csv2table array table,var wid,var hei,str fname
//csvファイルを元に2次元配列を作る
exist fname
if strsize=-1 : return -1
notesel buf
noteload fname
hei=notemax //表の縦の項目数
//表の横の項目数を調べる
wid=0 //表の横の項目数
repeat hei
noteget a,cnt
split a,",",results
if stat>wid : wid=stat
loop
//配列を作成
dim table,wid,hei
repeat hei
noteget a,cnt
split a,",",results
cnt0=cnt
repeat stat
table(cnt,cnt0)=int(results(cnt))
loop
loop
noteunsel
return
#deffunc table2csv array table,str fname
//2次元配列の内容をcsvに書き出す
buf=""
repeat length2(table)
cnt0=cnt
repeat length2(table)
buf=buf+str(table(cnt,cnt0))
if cnt<length2(table)-1 : buf=buf+","
loop
buf=buf+"\n"
loop
notesel buf
notesave fname
noteunsel
return
#global
//以下使用例。
//Excelでは横列をA,B,C……、縦列を1,2,3……と数えるが、HSPでは0,1,2……と数えることに注意
csv2table tbl0,wid0,hei0,"test0.csv"
//特定のセルのデータを読み込み
dim item,4
item(0)=tbl0(2,2) //C3
item(1)=tbl0(3,2) //D3
item(2)=tbl0(4,2) //E3
item(3)=tbl0(4,3) //E4
//書き出し
exist "test1.csv"
if strsize=-1 : dim tbl1,5,5 : else : csv2table tbl1,wid1,hei1,"test1.csv"
//たとえば、読み込んだデータをA2,B1,D4,E2に書き込みたい場合
tbl1(0,1)=item(0) //A2
tbl1(1,0)=item(1) //B1
tbl1(3,3)=item(2) //D4
tbl1(4,1)=item(3) //E2
table2csv tbl1,"test1.csv"
このような形でいかがでしょうか?
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
| |
|
2017/12/16(Sat) 18:39:07|NO.82041
ああ、申し訳ない、ミスがありました。
table2csvの部分は、以下に置き換えてください。
#deffunc table2csv array table,str fname
//2次元配列の内容をcsvに書き出す
buf=""
repeat length2(table)
cnt0=cnt
repeat length(table)
buf=buf+str(table(cnt,cnt0))
if cnt<length(table)-1 : buf=buf+","
loop
buf=buf+"\n"
loop
notesel buf
notesave fname
noteunsel
return
|
|
2017/12/17(Sun) 23:48:55|NO.82052
ありがとうございます。
作成して頂いたコードを実行させて頂きました。
読み込み書き込みが出来ました。
ありがとうございます。
ただtest1.csvの書き込んだファイルの中に
指定していないところに0が入ってました。
無知で申し訳ないのですが、0が入るのを消す方法はないでしょうか。
教えて頂けないでしょうか。
|
|
2017/12/18(Mon) 01:32:40|NO.82053
二次元配列の中に「空白をあらわす数値」(以下の例では-1)が入っていた場合は、
そこは空白として出力する仕様に変えてみました。
#module
#const global blank -1 //空白をあらわす数値。別な数値にしたい場合はここを変更。
#deffunc csv2table array table,var wid,var hei,str fname
//csvファイルを元に2次元配列を作る
exist fname
if strsize=-1 : return -1
notesel buf
noteload fname
hei=notemax //表の縦の項目数
//表の横の項目数を調べる
wid=0 //表の横の項目数
repeat hei
noteget a,cnt
split a,",",results
if stat>wid : wid=stat
loop
//配列を作成
dim table,wid,hei
repeat hei
noteget a,cnt
split a,",",results
cnt0=cnt
repeat stat
if results(cnt)="" {
table(cnt,cnt0)=blank
} else {
table(cnt,cnt0)=int(results(cnt))
}
loop
loop
noteunsel
return
#deffunc table2csv array table,str fname
//2次元配列の内容をcsvに書き出す
buf=""
repeat length2(table)
cnt0=cnt
repeat length(table)
if table(cnt,cnt0)!=blank : buf=buf+str(table(cnt,cnt0))
if cnt<length(table)-1 : buf=buf+","
loop
buf=buf+"\n"
loop
notesel buf
notesave fname
noteunsel
return
#global
//以下使用例。
//Excelでは横列をA,B,C……、縦列を1,2,3……と数えるが、HSPでは0,1,2……と数えることに注意
csv2table tbl0,wid0,hei0,"test0.csv"
//特定のセルのデータを読み込み
dim item,4
item(0)=tbl0(2,2) //C3
item(1)=tbl0(3,2) //D3
item(2)=tbl0(4,2) //E3
item(3)=tbl0(4,3) //E4
//書き出し
exist "test1.csv"
if strsize=-1 {
//空白をあらわす数値で初期化
dim tbl1,5,4
repeat 5
cnt0=cnt
repeat 4
tbl1(cnt0,cnt)=blank
loop
loop
} else {
csv2table tbl1,wid1,hei1,"test1.csv"
}
//たとえば、読み込んだデータをA2,B1,D4,E2に書き込みたい場合
tbl1(0,1)=item(0) //A2
tbl1(1,0)=item(1) //B1
tbl1(3,3)=item(2) //D4
tbl1(4,1)=item(3) //E2
table2csv tbl1,"test1.csv"
| |
|
2017/12/18(Mon) 11:26:59|NO.82057
沢渡 様
本当にありがとうございます。
おかげさまでやってみたいことが出来そうです。
ちなみに書き込む際に文字などは入れることが出来ますでしょうか?
tbl1(4,1)=item(3) //E2
item(3)を文字にしてみたいです。
(自分でやろうとしましたらエラーの連続で困惑しております)
度重なる質問で大変恐縮ですが、
よろしくお願いします。
|
|
2017/12/18(Mon) 17:20:15|NO.82058
何度も申し訳ありません。
小数を入れてもエラーが出てしまいました。
doubleを使ってみましたが、エラーになってしまいます。
ご教授頂けないでしょうか。
|
|
2017/12/18(Mon) 17:32:20|NO.82059
上のサンプルは、dim命令で作った整数の配列をcsv化することを目的としているので、
文字列や実数(小数)を扱うことはできません。
以下は文字列の配列に対応させたバージョンです。
前のものと違い、数値を直接書き込むことはできないので、
書き込む際はstr()で文字列化してから書き込んでください。
(test00.cvsの内容)
あ,い,う,え,お
か,き,く,け,こ
さ,し,す,せ,そ
た,ち,つ,て,と
(以下コード)
//文字列対応版
#module
#const global txt_max 30 //各セルの最大文字数
#deffunc csv2table array table,var wid,var hei,str fname
//csvファイルを元に、「文字列の」2次元配列を作る
exist fname
if strsize=-1 : return -1
notesel buf
noteload fname
hei=notemax //表の縦の項目数
//表の横の項目数を調べる
wid=0 //表の横の項目数
repeat hei
noteget a,cnt
split a,",",results
if stat>wid : wid=stat
loop
//配列を作成
sdim table,txt_max,wid,hei
repeat hei
noteget a,cnt
split a,",",results
cnt0=cnt
repeat stat
table(cnt,cnt0)=results(cnt)
loop
loop
noteunsel
return
#deffunc table2csv array table,str fname
//2次元配列の内容をcsvに書き出す
buf=""
repeat length2(table)
cnt0=cnt
repeat length(table)
buf=buf+table(cnt,cnt0)
if cnt<length(table)-1 : buf=buf+","
loop
buf=buf+"\n"
loop
notesel buf
notesave fname
noteunsel
return
#global
//以下使用例。
//Excelでは横列をA,B,C……、縦列を1,2,3……と数えるが、HSPでは0,1,2……と数えることに注意
csv2table tbl0,wid0,hei0,"test00.csv"
//特定のセルのデータを読み込み
sdim item,txt_max,4
item(0)=tbl0(2,2) //C3
item(1)=tbl0(3,2) //D3
item(2)=tbl0(4,2) //E3
item(3)=tbl0(4,3) //E4
//書き出し
exist "test1.csv"
if strsize=-1 {
sdim tbl1,txt_max,5,4
} else {
csv2table tbl1,wid1,hei1,"test1.csv"
}
//読み込んだデータをA2,B1,D4,E2に書き込む
tbl1(0,1)=item(0) //A2
tbl1(1,0)=item(1) //B1
tbl1(3,3)=item(2) //D4
tbl1(4,1)=item(3) //E2
//直接文字を書き込む
tbl1(2,2)="hoge"
//数値(整数)を書き込む場合
tbl1(2,3)=str(100) //数値を書き込む場合は、str()で囲んで文字列として扱わないとエラーになるので、注意
//実数を書き込む場合
a=123.456
tbl1(4,3)=strf("%3.3f",a) //実数を書き込む場合は、strfで整数部と小数部の桁数を指定して書き込むのが望ましい
//(単純にstrで文字列化すると、小数部が長くなりすぎるので)
table2csv tbl1,"test01.csv"
csvの書式はとても単純なものですから、「一行のデータをコンマで区切り、
数行にわたって記述したテキストデータ」だということをおさえておけば、
もっと簡易な方法でも出力できると思います。
| |
|
2017/12/18(Mon) 17:42:31|NO.82060
沢渡 様
大変ありがとうございます。
何度も教えて頂き本当に助かりました。
始めたばかりで挫折しそうでしたが、
沢渡様のおかげでなんとか次のステップへ行けそうです。
教えて頂いたコードを勉強しながら、頑張ろうと思います。
|
|
2017/12/19(Tue) 12:04:37|NO.82062
沢渡 様
度々すみません。
もとのtest00.csvを数値に変え、
item(0)=tbl0(2,2)を
文字から数字に直し文字に戻そうとしたのですが、
item(0)=double(item(0))+500
item(0)=str(item(0))
item(0)ですとエラーがなかったのですが、
なぜかitem(1)ですとエラーが出てしまいます。
ご教授頂けないでしょうか?
|
|
2017/12/19(Tue) 18:25:52|NO.82063
itemはsdimで初期化している文字列配列ですから、
文字列以外のものを代入してはいけません。
item(0)=double(item(0))+500
の直後にstopを置いて、デバッグウィンドウを見ればわかるのですが、
実数を代入したせいでitemが実数変数に変わってしまい、その際に配列化も
解除されてしまっているのです。
(だからitem(1)を参照しようとすると『配列の要素が無効』エラーになる)
item(0)=double(item(0))+500
item(0)=str(item(0))
を
x=double(item(0))+500
item(0)=str(x)
等と変え、他の変数を経由して処理するようにしてください。
|
|
2017/12/20(Wed) 08:49:47|NO.82066
沢渡 様
ご説明いただいた上にコードも記載していただいて、
ご助力大変ありがとうございます。
納得し解決できました。
本当にありがとうございます。
|
|