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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
|
-
|
|
|
!
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#module "randumfile_I_O"
#define global FILE_NUMBER 10 #define global FILE_RECORD_SIZE 1024 #define TEMP_FILE_NAME "RandumAccessTemp.tmp"
#uselib "kernel32"
#func MoveFileA "MoveFileA" sptr,sptr
#defcfunc fileopen str filename
n=0
repeat FILE_NUMBER
if openswitch.cnt ! 1 {
filename_no = cnt
n=1
break
}
loop
if n=0 : return -1 tempfile.filename_no = getpath(filename,32)
if tempfile.filename_no="" {
temp = dir_cur + "\\" + filename
tempfile.filename_no = dir_cur + "\\" + TEMP_FILE_NAME
} else {
temp = filename
tempfile.filename_no = tempfile.filename_no + "\\" + TEMP_FILE_NAME
}
fl.filename_no=temp
temp=""
exist fl.filename_no
if strsize=-1 {
; あらかじめファイルを作っておかなければ、それ以降アクセスエラー
bsave fl.filename_no,temp,0
}
openswitch.filename_no = 1
return filename_no
;-------------------------------------------------------------------------
; ランダムファイルクローズ (命令)
;
; fileclose p1 p1 : ファイルナンバー
;-------------------------------------------------------------------------
#deffunc fileclose int f_no
; ファイルナンバーをゼロにするだけ
openswitch.f_no = 0
return n
;-------------------------------------------------------------------------
; データイニシャライズ (関数)
;
; filedatainit p1,p2,p3,p4
; p1 : fileopenで返されたファイルナンバー
; p2 : 1レコード内のデータの個数
; p3 : この配列に1つ1つのデータサイズを予めp2個入力
; p4 : 1レコード内の各p2個p3サイズの文字列配列データ
; これを実行するとp4の内容はクリアされます。
;
; 戻り値 : レコード総数が返り、空なら0、ファイルが無ければ-1。
; fileopenの後に必ず呼び出してください。
;-------------------------------------------------------------------------
#defcfunc filedatainit int f_no,int d_num,array d_sz,array data
if openswitch.f_no ! 1 : return -1
; BASICでいうところのFIELD宣言みたいなもの
_num.f_no=d_num
datasize.f_no = 0
repeat _num.f_no
datasize.f_no += d_sz.cnt
n=cnt
repeat d_sz.cnt
poke data.n,cnt,0x00 ; ゴミが溜まるので...
loop
loop
exist fl.f_no
if strsize!-1 {
if (strsize<datasize.f_no) | (strsize=0) : return 0
return int(strsize/datasize.f_no)
}
return -1
;--------------------------------------------------------------------
; 現在のファイルのレコード総数の取得 (関数)
;
; filedatamax p1
; p1 : fileopenで返されたファイルナンバー
;
; 戻り値 : 失敗-1。
;
; この関数を実行すると、現在オープンされているランダムファイルの
; レコード総数が返ります。
; filedatainitもレコード総数を返しますが、この関数はデータを空に
; しません。
; 一度filedatainitを呼び出せば、後はこのfiledatamaxでも可能だと
; 思います。
;--------------------------------------------------------------------
#defcfunc filedatamax int f_no
if openswitch.f_no ! 1 : return -1
exist fl.f_no
if strsize!-1 {
; ファイルサイズを1レコード長で割ったものをレコード総数とする
if (strsize<datasize.f_no) | (strsize=0) : return 0
return int(strsize/datasize.f_no)
}
return -1
;-------------------------------------------------------------------------
; レコード内の各データクリア (命令)
;
; filedataclear p1,p2,p3
; p1 : fileopenで返されたファイルナンバー
; p2 : 1つ1つのデータサイズが入った配列
; p3 : 1レコード内の各p2サイズの文字列データ配列
; これを実行するとp3の内容はクリア(全てNULLクリア)されます。
;-------------------------------------------------------------------------
#deffunc filedataclear int f_no,array d_sz,array data
if openswitch.f_no ! 1 : return
repeat _num.f_no
n=cnt
repeat d_sz.cnt
poke data.n,cnt,0x00 ; ゴミが溜まるので...
loop
loop
return
;--------------------------------------------------------------------
; 1レコードの読み込み (関数)
;
; filedatainput p1,p2,p3,p4
; p1 : fileopenで返されたファイルナンバー
; p2 : 何レコード目を読み込むかを指定 (0〜)
; p3 : 1つ1つのデータサイズが入った配列
; p4 : 1レコード内の各p3サイズの文字列データ配列
; これを実行するとレコード指定したデータがp4の配列に入ります。
;
; 戻り値 : 失敗もしくはファイルが無ければ-1。
;---------------------------------------------------------------------
#defcfunc filedatainput int f_no,int nset,array d_sz,array data
if openswitch.f_no ! 1 : return -1
sizeofset=datasize.f_no*nset
exist fl.f_no
if strsize!-1 {
if strsize<sizeofset : return -1
; 1レコード長に指定レコード番号をかけたところから1レコード長読み込む
bload fl.f_no,buf,datasize,sizeofset
i=0
; 1レコードから各データ配列に分解
repeat _num.f_no
memcpy data.cnt,buf,d_sz.cnt,0,i
poke data.cnt,d_sz.cnt,0x00
i+=d_sz.cnt
loop
return 1
}
return -1
;--------------------------------------------------------------------
; 1レコードの(上書き)書き込み (関数)
;
; filedataoutput p1,p2,p3,p4
; p1 : fileopenで返されたファイルナンバー
; p2 : 何レコード目に上書きして書き込むかを指定 (0〜)
; p3 : 1つ1つのデータサイズが入った配列
; p4 : 1レコード内に書き込むp3サイズの文字列データ配列
;
; 戻り値 : 失敗もしくはファイルが無ければ-1。
;
; この関数を実行すると、指定したレコード番号の位置に上書きされ、
; そのレコード番号のデータは消されます。
;--------------------------------------------------------------------
#defcfunc filedataoutput int f_no,int nset,array d_sz,array data
if openswitch.f_no ! 1 : return -1
sizeofset=datasize.f_no*nset
i=0
exist fl.f_no
if strsize!-1 {
; 各データ配列から1レコードに連結
repeat _num.f_no
memcpy buf,data.cnt,d_sz.cnt,i,0
i+=d_sz.cnt
loop
; 1レコード長に指定レコード番号をかけたところから1レコード長書き込む
bsave fl.f_no,buf,datasize.f_no,sizeofset
return 1
}
return -1
;--------------------------------------------------------------------
; 1レコードの(挿入)書き込み (関数)
;
; filedatainsert p1,p2,p3,p4
; p1 : fileopenで返されたファイルナンバー
; p2 : 何レコード目に挿入して書き込むかを指定 (0〜)
; p3 : 1つ1つのデータサイズが入った配列
; p4 : 1レコード内に書き込むp3サイズの文字列データ配列
;
; 戻り値 : 失敗-1。
;
; この関数を実行すると、指定したレコード番号の位置に挿入され、
; それ以降のレコードが繰り下がります。
;--------------------------------------------------------------------
#defcfunc filedatainsert int f_no,int nset,array d_sz,array data
if openswitch.f_no ! 1 : return -1
sdim temp1,128,_num.f_no
repeat _num.f_no
temp1.cnt = data.cnt
loop
exist tempfile.f_no
if strsize ! -1 {
delete tempfile.f_no
wait 10
}
bcopy fl.f_no,tempfile.f_no ; エラーになっても元ファイルは無傷にするため
tn=fileopen(tempfile.f_no) ; 現在開いているファイルと同じサイズでオープン
if tn = -1 : return -1
dno1=filedatainit(tn,_num.f_no,d_sz,data)
if dno1 ! -1 {
if dno1 > nset {
n=dno1-1
while n>=nset
if filedatainput(tn,n,d_sz,data) ! -1 {
if filedataoutput(tn,n+1,d_sz,data) = -1 {
fileclose tn
return -1
}
} else {
fileclose tn
return -1
}
n-
wend
}
repeat _num.f_no
data.cnt = temp1.cnt
loop
if filedataoutput(tn,nset,d_sz,data) = -1 {
fileclose tn
return -1
}
} else {
fileclose tn
return -1
}
delete fl.f_no
wait 20
MoveFileA varptr(tempfile.f_no),varptr(fl.f_no)
fileclose tn
return 1
;--------------------------------------------------------------------
; 1レコードの削除 (関数)
;
; filedatadelete p1,p2,p3,p4
; p1 : fileopenで返されたファイルナンバー
; p2 : 何レコード目を削除するかを指定 (0〜)
; p3 : 1つ1つのデータサイズが入った配列
; p4 : 1レコード内に書き込むp3サイズの文字列データ配列
;
; 戻り値 : 失敗-1。
;
; この関数を実行すると、指定したレコードが消されそれ以降の
; レコードが繰り上がります。
;--------------------------------------------------------------------
#defcfunc filedatadelete int f_no,int nset,array d_sz,array data
if openswitch.f_no ! 1 : return -1
exist tempfile.f_no
if strsize ! -1 {
delete tempfile.f_no
}
tn=fileopen(tempfile.f_no) ; エラーになっても元ファイルは無傷にするため
if tn = -1 : return -1 ; 現在開いているファイルと同じサイズでオープン
if filedatainit(tn,_num.f_no,d_sz,data) ! -1 {
dno1=filedatainit(f_no,_num.f_no,d_sz,data)
if dno1 ! -1 {
dno2=0
repeat dno1
if nset!cnt {
if filedatainput(f_no,cnt,d_sz,data) ! -1 {
if filedataoutput(tn,dno2,d_sz,data) ! -1 {
dno2+
} else {
fileclose tn
return -1
}
} else {
fileclose tn
return -1
}
}
loop
} else {
fileclose tn
return -1
}
delete fl.f_no
wait 20
MoveFileA varptr(tempfile.f_no),varptr(fl.f_no)
fileclose tn
} else {
return -1
}
return 1
;--------------------------------------------------------------------
; ランダムファイルをCSVファイルに変換する (命令)
;
; csv_data_output p1,p2,p3,p4
; p1 : CSVファイルに変換して書き込むためのファイル名
; p2 : fileopenで返されたファイルナンバー
; p3 : 1つ1つのデータサイズが入った配列
; p4 : 1レコード内に書き込むp3サイズの文字列データ配列
;--------------------------------------------------------------------
#deffunc csv_data_export str csvfilename,int f_no,array d_sz,array data
notesel rfd
rfd=""
wcb=" " : poke wcb,0,0x22
exist fl.f_no
if strsize!-1 {
repeat filedatainit(f_no,_num.f_no,d_sz,data)
if filedatainput(f_no,cnt,d_sz,data) ! -1 {
buf=wcb
repeat _num.f_no
buf += data.cnt
if _num.f_no-1 ! cnt : buf = buf + wcb + "," + wcb
loop
buf += wcb
noteadd buf,cnt,0
}
loop
notesave csvfilename ; デスクトップには書き込めないことがあります
}
return
;--------------------------------------------------------------------
; CSVファイルをランダムファイルに変換する (命令)
;
; csv_data_input p1,p2,p3
; p1 : ランダムファイルに変換するためのCSVファイル名
; p2 : fileopenで返されたファイルナンバー
; p3 : 1つ1つのデータサイズが入った配列
; p4 : 1レコード内に書き込むp3サイズの文字列データ配列
;
; 注 : fileopen(),filedatainit() を実行しておくこと
; filedatainit() で指定した1レコード内のデータ個数より
; 多い場合、切り捨てられ、少ない場合はNULLになります。
;--------------------------------------------------------------------
#deffunc csv_data_inport str csvfilename,int f_no,array d_sz,array data
notesel rfd
rfd=""
exist csvfilename
if strsize!-1 {
noteload csvfilename
exist fl.f_no
if strsize!-1 {
repeat notemax
noteget buf,cnt
filedataclear f_no,d_sz,data
dp=0 : rp=0 : ck=0
repeat _num.f_no
temp=cnt
repeat
c=peek(buf,dp)
if c=',' | c=0x00 {
poke data.temp,rp,0x00
if c=0x00 : ck=1 : break
rp=0 : dp+
break
} else {
if c ! 0x22 {
; ダブルコーテーションは省く
poke data.temp,rp,c
rp+
}
dp+
}
loop
if ck=1 : break
loop
if filedataoutput(f_no,cnt,d_sz,data) ! -1 {
; 何もしない
}
loop
}
}
return
#global
dim _num@randumfile_I_O,FILE_NUMBER ; 1レコード内のデータ個数
dim datasize@randumfile_I_O,FILE_NUMBER ; 1レコードのサイズ
dim openswitch@randumfile_I_O,FILE_NUMBER ; fileopenでオープンしているかどうか
sdim fl@randumfile_I_O,256,FILE_NUMBER ; 最高10個のランダムファイルが扱えます
sdim buf@randumfile_I_O,FILE_RECORD_SIZE ; 1レコードの書き込み用バッファ
sdim tempfile@randumfile_I_O,256,FILE_NUMBER ; テンポラリファイル名格納
repeat FILE_NUMBER
openswitch@randumfile_I_O.cnt = 0
loop
|