|
|
2015/11/3(Tue) 04:32:52|NO.72715
こんばんは、教えてください。
例えば、下記のようなCSVデータを
TEST1.CSV (5000件ほど)
性,名,写真複数,県名,住所
AAA,BBB,"C1.JPG,C2.JPG,C3.JPG",DDD,EEE
AA1,BB1,"C2.JPG,C3.JPG,C4.JPG,C5.JPG",DD1,EE1
.....
TEST2.CSV 順番入れ替え
県名,写真複数,性
DDD,"C1.JPG,C2.JPG,C3.JPG",AAA
DD1,"C2.JPG,C3.JPG,C4.JPG,C5.JPG",AA1
....
TEST1.CSVからデータの順番を入れ替えて、
項目も減らしたりして新たなTEST2.CSVを作りたいのですが
どのようにすればよいでしょうか?
写真複数は""で囲んで、枚数は変動します
どうぞ宜しくお願いします。
|
|
2015/11/3(Tue) 10:03:45|NO.72720
CSVの仕様上文字列は引用符が必要だとかおいといて
notegetで一行ずつ読み出す
カンマで分割する
ひとつずつ引用符を調べて連結する
以上を繰り返す。
|
|
2015/11/3(Tue) 12:04:43|NO.72724
skybleuさん、どうもありがとうございます。
その方法ですと、"00.JPG,01.JP"のようにダブルクォーテーションで囲まれたデータが分割されてしまいました。
””で囲まれた部分は一つの文字列として取り出したいのです。
GENKIさん、どうもありがとうございます
googleでヒットしたしたのですが、使い方わからずエラーになって動きませんでした
具体的にどのようにすれば良いか教えて頂けないでしょうか?
どうぞ宜しくお願いします。
思っているようなサンプルがっ見つかりましたので、動かしてみました。
#include "hspda.as"
dialog "", 16, "" // ファイルの選択(CSVファイルを選択)
filename = refstr
sdim buf, 0xffff // ファイルの内容を格納
sdim _line, 0xfff // 1行分の文字列を格納
sdim tmp, 0xfff // 一時的に使用
len = 0 // 取得した行数
notesel buf // メモリノートパッドの初期化
noteload filename // ファイルの読み込み
sdim records, 0xfff, notemax // CSVの行数分メモリを確保
// メインループ
repeat notemax
noteget _line, cnt // 1行取得
// 1行分をメモリノートパッド形式でCSVに変換し、
// records.cntに保存
csvnote tmp, _line
records.cnt = tmp
len++ // 行数インクリメント
loop
// 表示テスト。records配列をrepeatで回し、strtrimで「"」をトリミングして表示
for i, 0, len, 1
cls
mes "【" + (i + 1) + "行目】"
notesel records.i
repeat notemax
noteget _line, cnt
mes "" + (cnt + 1) + "列目:" + strtrim(_line, 0, '"')
loop
next
stop
------
TEST.CSV 3行になっています。
商品ID,公開ステータス(ID),商品名,ショップ用メモ欄,商品説明(一覧),商品説明(詳細),検索ワード,フリーエリア,商品削除フラグ,商品画像,商品カテゴリ(ID),商品種別(ID),規格分類1(ID),規格分類2(ID),発送日目安(ID),商品コード,在庫数,在庫数無制限フラグ,販売制限数,通常価格,販売価格,送料,商品規格削除フラグ
,1,IT-0001,,IT-0001,IT-0001,IT-0001,,,"IT-0001/IT-0001_00.JPG,IT-0001/IT-0001_01.JPG,IT-0001/IT-0001_02.JPG,IT-0001/IT-0001_03.JPG,IT-0001/IT-0001_04.JPG,IT-0001/IT-0001_05.JPG,IT-0001/IT-0001_06.JPG,IT-0001/IT-0001_07.JPG,IT-0001/IT-0001_08.JPG,IT-0001/IT-0001_09.JPG",1,1,,,,IT-0001,1,0,,,99999,,
,1,IT-0002,,IT-0002,IT-0002,IT-0002,,,"IT-0002/IT-0002_00.JPG,IT-0002/IT-0002_01.JPG,IT-0002/IT-0002_02.JPG,IT-0002/IT-0002_03.JPG,IT-0002/IT-0002_04.JPG",1,1,,,,IT-0002,1,0,,,99999,,

| |
|
2015/11/3(Tue) 12:10:11|NO.72725
CSVデータが分かりにくいので、下記に書きなおしました。
TEST.CSV
商品ID,公開ステータス(ID),商品名,ショップ用メモ欄,商品説明(一覧),商品説明(詳細),検索ワード,フリーエリア,商品削除フラグ,商品画像,商品カテゴリ(ID),商品種別(ID),規格分類1(ID),規格分類2(ID),発送日目安(ID),商品コード,在庫数,在庫数無制限フラグ,販売制限数,通常価格,販売価格,送料,商品規格削除フラグ
2222,1,IT-0001,,IT-0001,IT-0001,IT-0001,,,"IT-0001/IT-0001_00.JPG,IT-0001/IT-0001_01.JPG,IT-0001/IT-0001_02.JPG,IT-0001/IT-0001_03.JPG,IT-0001/IT-0001_04.JPG,IT-0001/IT-0001_05.JPG,IT-0001/IT-0001_06.JPG,IT-0001/IT-0001_07.JPG,IT-0001/IT-0001_08.JPG,IT-0001/IT-0001_09.JPG",1,1,,,,IT-0001,1,0,,,99999,0,終
3333,1,IT-0002,,IT-0002,IT-0002,IT-0002,,,"IT-0002/IT-0002_00.JPG,IT-0002/IT-0002_01.JPG,IT-0002/IT-0002_02.JPG,IT-0002/IT-0002_03.JPG,IT-0002/IT-0002_04.JPG",1,1,,,,IT-0002,1,0,,,99999,2,終
|
|
2015/11/3(Tue) 13:59:48|NO.72726
> googleでヒットしたしたのですが、使い方わからずエラーになって動きませんでした
ありがとうございます。
こういうふうに、わからないところがあった時にちゃんとどこがわからないと言っていただけると回答がしやすくなるので助かります。
動くように修正したものを用意しました。
といってもstrrepをm_strrepに置換しただけなんですけどね。
データを読み込むサンプル付きです。どうぞ。
;###################################################
; モジュール
#module
;置換
;strin = strrep( _strin, target, replace)
; _strin 元になる文字列
; target 置換前文字列(検索する文字列)
; replace 置換後文字列(置き換える文字列)
; strin 置換作業後の文字列
#defcfunc m_strrep str _strin,str target,str replace
strin = _strin
position = 0
repeat
await 1
position1 = instr( strin, position, target )
if position1 = -1 : break
position += position1 ;検索結果位置
strin = strmid( strin, 0, position) + replace + strmid( strin, position + strlen(target), strlen(strin) )
position += strlen( replace ) ;次の検索開始位置
loop
return strin
;2重ダブルクォーテーションをカットする
;strin = cutwqt( _strin )
; _strin 元になる文字列
; strin 変換後文字列
;
;例:「"テスト""文字列""テスト"」→「テスト"文字列"テスト」
#defcfunc cutwqt str _strin
strin = _strin
if strmid( strin, 0, 1 ) = "\"" {
strin = strmid( strin, 1, strlen(strin)-2 )
position = 0
repeat
await 1
position1 = instr( strin, position, "\"" )
if position1 = -1 : break
position += position1 ;検索結果位置
if strmid( strin, position + 1, 1 ) = "\"" : p = 2 : else : p = 1
strin = strmid( strin, 0, position) + strmid( strin, position+1, strlen(strin) )
position += p ;次の検索開始位置
loop
}
return strin
#global
#module
;CSV形式のセル内書式を通常の書式に変換する
;strin = cell2str( _strin )
; _strin 元になる文字列
; strin 変換後文字列
#defcfunc cell2str str _strin
strin = _strin
if strlen(strin)!0 {
strin = _strin
;改行コードの置換
strsrch = "" : poke strsrch,0,10 ;改行コード
strin = m_strrep( strin, strsrch, "\n")
;ダブルクォーテーションの置換
strin = cutwqt( strin )
}
return strin
#global
;csvの1行を配列に変換。
;csvstr2 _arrayout, _strin
; _arrayout 結果を入れる文字列型配列変数
; _strin 元になる文字列
; stat 使用した配列の数
;
;_arrayoutは事前に
; sdim _arrayout, 256, 10
;などとして十分な配列を確保しておいてください。
;
#module
#deffunc csvstr2 array _arrayout, str _strin
strin = _strin
cellcnt = 0
flg = 0 ;ダブルクォーテーションで始まるセルを検出結果
st = 0 ;使用した配列の数
fcellend = 0 ;1行読み終わりフラグ
scln = 0 ;区切り間文字数カウント
repeat
await 0
;区切り検索
;1文字目をチェック
if strmid( strin, cellcnt, 1 ) = "\"" {
flg = 1 ;ダブルクォーテーションで始まるセルを検出。
kugiri = "\""
} else {
flg = 0
kugiri = ","
}
;文字列抽出
if flg = 1 {
;\"スタートのとき
;終わりを探す
scln = 1 ;区切り文字の次の文字から
repeat
await
k = instr( strin, cellcnt + scln, "\"" )
if k!-1 {
scln += k + 1
;if strmid( strin, cellcnt + scln, 1 ) = "\"" : ;\"\"はスルー
if strmid( strin, cellcnt + scln, 1 ) = "," : break ;\",で一区切り
if strmid( strin, cellcnt + scln, 2 ) = "\n" : fcellend = 1 : break ;\"\nで処理終了
scln++
} else {
scln = strlen(strin) - cellcnt
fcellend = 1
break
}
loop
} else {
;通常
getstr stra, strin, cellcnt, ',' ;カンマ、改行、終端のうち一番近い方を探す(1024byteまで。straはダミー)
scln = strsize
if stat = ',' { ;,まで読み出された
scln--
} else { ;終端か\nまで読み出された
fcellend = 1
if stat = 13 : scln -= 2 ;\nまで読み出された
}
}
_arrayout.cnt = strmid( strin, cellcnt, scln ) ;区切り間の文字を出力
cellcnt += scln + strlen(kugiri) ;次の検索開始位置へ
if fcellend ! 0 : st = cnt+1 : break
loop
return st
#global
;###################################################################
; モジュールはここまで
;###################################################################
sdim data, 1024,3
sdim getcell, 256,100
sdim cell, 256, 100, 3
dim cell_cnt, 3
data(0) = "商品ID,公開ステータス(ID),商品名,ショップ用メモ欄,商品説明(一覧),商品説明(詳細),検索ワード,フリーエリア,商品削除フラグ,商品画像,商品カテゴリ(ID),商品種別(ID),規格分類1(ID),規格分類2(ID),発送日目安(ID),商品コード,在庫数,在庫数無制限フラグ,販売制限数,通常価格,販売価格,送料,商品規格削除フラグ"
data(1) = "2222,1,IT-0001,,IT-0001,IT-0001,IT-0001,,,\"IT-0001/IT-0001_00.JPG,IT-0001/IT-0001_01.JPG,IT-0001/IT-0001_02.JPG,IT-0001/IT-0001_03.JPG,IT-0001/IT-0001_04.JPG,IT-0001/IT-0001_05.JPG,IT-0001/IT-0001_06.JPG,IT-0001/IT-0001_07.JPG,IT-0001/IT-0001_08.JPG,IT-0001/IT-0001_09.JPG\",1,1,,,,IT-0001,1,0,,,99999,0,終"
data(2) = "3333,1,IT-0002,,IT-0002,IT-0002,IT-0002,,,\"IT-0002/IT-0002_00.JPG,IT-0002/IT-0002_01.JPG,IT-0002/IT-0002_02.JPG,IT-0002/IT-0002_03.JPG,IT-0002/IT-0002_04.JPG\",1,1,,,,IT-0002,1,0,,,99999,2,終"
;----------
; データ取り出し
repeat 3
; カンマ区切りのデータを取り出し
csvstr2 getcell, data(cnt)
cell_cnt(cnt)=stat
; 取り出した1行分のデータを移し替え
i = cnt
repeat stat
cell(cnt,i) = getcell(cnt)
loop
loop
;----------
; 配列変数に変換したデータを表示
repeat 3
i = cnt
pos cnt*200, 0
repeat cell_cnt(cnt)
mes "" + cnt + " : " + cell(cnt, i)
loop
loop
;----------
; 画像ファイル名の部分を分割して表示
screen 1
;1個目
csvstr2 getcell, cell2str(cell(9, 1))
repeat stat
mes ""+ cnt + " : " + getcell(cnt)
loop
;2個目
pos 300, 0
csvstr2 getcell, cell2str(cell(9, 2))
repeat stat
mes ""+ cnt + " : " + getcell(cnt)
loop

| |
|
2015/11/3(Tue) 14:11:01|NO.72728
> 思っているようなサンプルがっ見つかりましたので、動かしてみました。
このサンプルはどこのものか知らないのですが、このままだと結果がまともに表示されませんね。
データそのものはきちんと取得できているので表示だけの問題です。
28行目のclsを削除して
pos i*100,0
に書き変えてください。
clsを実行しちゃうとそれ以前に書いたものを消しちゃうので、1〜2行めまでの結果が消えてしまいます。
|
|
2015/11/3(Tue) 15:00:06|NO.72731
GENKIさん
こんにちは、
プログラムありがとうございます
無事動きました^^)/
これを参考にして、作っていきたいと思います。
本当に有難うございましたm(_ _)m
|
|