HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2017
1216
MSTcsvの読込みと書込み12解決


MST

リンク

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



MST

リンク

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"



MST

リンク

2017/12/18(Mon) 11:26:59|NO.82057

沢渡 様

本当にありがとうございます。
おかげさまでやってみたいことが出来そうです。

ちなみに書き込む際に文字などは入れることが出来ますでしょうか?
tbl1(4,1)=item(3) //E2
item(3)を文字にしてみたいです。
(自分でやろうとしましたらエラーの連続で困惑しております)

度重なる質問で大変恐縮ですが、
よろしくお願いします。



MST

リンク

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の書式はとても単純なものですから、「一行のデータをコンマで区切り、
数行にわたって記述したテキストデータ」だということをおさえておけば、
もっと簡易な方法でも出力できると思います。




MST

リンク

2017/12/18(Mon) 17:42:31|NO.82060

沢渡 様
大変ありがとうございます。
何度も教えて頂き本当に助かりました。

始めたばかりで挫折しそうでしたが、
沢渡様のおかげでなんとか次のステップへ行けそうです。
教えて頂いたコードを勉強しながら、頑張ろうと思います。



MST

リンク

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)
等と変え、他の変数を経由して処理するようにしてください。



MST

リンク

2017/12/20(Wed) 08:49:47|NO.82066

沢渡 様

ご説明いただいた上にコードも記載していただいて、
ご助力大変ありがとうございます。
納得し解決できました。
本当にありがとうございます。



ONION software Copyright 1997-2023(c) All rights reserved.