10
20
30 :
40 ON ERROR REPORT:PROCClose_All:PRINT" at line ";ERL:END
50 A$=FNOS_GetEnv:d$=".":s$="/":IFos%>31:d$="\":s$="." ELSE IF(os%AND8):d$="/":s$="."
60 file$=FNcl("",0):sort$=":"+FNcl("",0)
70 IF file$="" OR sort$=":":PRINT"Syntax: CSVSort <file> <fields>":A%=INKEY(200):QUIT
80 up%=OPENIN(file$)
90 :
100 A$=GET$#up%:IF A$="":A$=GET$#up% :
110 max%=-1:REPEAT:max%=max%+1
120 IF LEFT$(A$,1)="""":A$=MID$(A$,INSTR(A$,"""",2))
130 A%=INSTR(A$,","):IF A%:A$=MID$(A$,A%+1)
140 UNTILA%=0 :
150 :
160 A%=0:REPEAT :
170 A$=GET$#up%:IF A$="":A$=GET$#up%
180 num%=num%+LENA$
190 A%=A%+1
200 UNTIL A%=10 OR EOF#up%
210 num%=EXT#up% DIV (num%/10.5) :
220 :
230 PRINT;num%;" records, ";max%+1;" fields";
240 IF END+num%*300>HIMEM THEN HIMEM=(END+num%*300) AND -4
250
260 DIM head$(max%),line$(max%),data$(num%,max%)
270 :
280 PRINT'"Reading...";
290 PTR#up%=0:PROCcsv_rd(up%,head$()) :
300 record%=0
310 REPEAT :
320 PROCcsv_rd(up%,line$())
330 FOR A%=0 TO max%:data$(record%,A%)=line$(A%):NEXT A%
340
350 record%=record%+1
360 UNTIL EOF#up% OR record%>num%:CLOSE#up%:up%=0
370 IF record%>num%:PRINT '"Bad estimate of number of records":A%=INKEY(200):QUIT
380 num%=record%-1
390
400
410 :
420 PRINT'"Sorting...";
430 REPEAT :
440 A%=FNinstrR(sort$,":"):field%=VALMID$(sort$,A%+1):sort$=LEFT$(sort$,A%-1)
450 isanum%=(STR$VALdata$(1,field%)=data$(1,field%))
460 PRINT'" by field ";field%;": ";head$(field%);
470 PROCsort(0,num%,field%,isanum%)
480 UNTIL sort$=""
490 :
500 PRINT'"Saving...";
510 up%=OPENOUT(file$) :
520 PROCcsv_wr(up%,head$())
530 FOR record%=0 TO num%-1
540 FOR A%=0 TO max%:line$(A%)=data$(record%,A%):NEXT A%
550 PROCcsv_wr(up%,line$())
560 NEXT record%
570 CLOSE#up%:up%=0:PRINT'"Done"
580 QUIT
590 :
600 DEFPROCClose_All
610 up%=up%:IFup%:A%=up%:up%=0:CLOSE#A%
620 ENDPROC
630 :
640 DEFPROCcsv_rd(i%,array$())
650 LOCAL n%:n%=0:array$()="":A$=GET$#i%:IFA$="":A$=GET$#i%
660 A$=A$+","
670 REPEAT
680 IF LEFT$(A$,2)="=""":A$=MID$(A$,2)
690 IF LEFT$(A$,1)="""" THEN
700 A%=INSTR(A$,""",",2)+1:array$(n%)=MID$(A$,2,A%-3)
710 ELSE
720 A%=INSTR(A$,","):array$(n%)=LEFT$(A$,A%-1)
730 ENDIF
740 A$=MID$(A$,A%+1):n%=n%+1
750 UNTILA$=""
760 ENDPROC
770 :
780 DEFPROCcsv_wr(o%,array$())
790 LOCAL n%,q%:n%=DIM(array$(),1)
800 FOR A%=0 TO n%:A$=array$(A%)
810 q%=INSTR(A$,",")
820 IF q%=0:q%=(ASCA$=48)AND(INSTR(A$,"/")=0) :
830 IF q%=0:IFVALLEFT$(A$,1):q%=INSTR(A$,"E") :
840 IF q%=0:q%=LENSTR$VALA$>8 :
850 IF q%=0:IFVALA$:q%=INSTR(A$,"/")AND(ASCA$<>48):
860 IF q%=0:q%=LEFT$(A$,1)="-" :
870 IF q%=0:q%=MID$(A$,3,1)=" "ANDMID$(A$,7,1)=" ":
880 IF q%:A$=""""+A$+"""":IFINSTR(A$,",")=0:A$="="+A$
890 BPUT#o%,A$;:IF A%<>n%:BPUT#o%,",";
900 NEXT A%:BPUT#o%,""
910 ENDPROC
920 :
930 DEFPROCsort(start%,end%,field%,isanum%)
940 LOCAL i%,j%,n%,m%:n%=end%
950 REPEAT:m%=start%
960 FOR i%=1 TO n%-1
970 IF isanum% THEN
980 IF VALdata$(i%-1,field%)>VALdata$(i%,field%):PROCswap(i%-1,i%):m%=i%
990 ELSE
1000 IF data$(i%-1,field%)>data$(i%,field%):PROCswap(i%-1,i%):m%=i%
1010 ENDIF
1020 NEXT i%:n%=m%
1030 UNTIL n%=0
1040 ENDPROC
1050 :
1060 DEFPROCswap(i%,j%):FOR A%=0 TO max%:SWAP data$(i%,A%),data$(j%,A%):NEXT A%:ENDPROC
1070 :
1080 DEFFNinstrR(A$,B$):A%=LENA$+1:REPEATA%=A%-1:UNTILMID$(A$,A%,LENB$)=B$ OR A%=0:=A%
1090 :
1100 DEFFNOS_GetEnv:A%=0:X%=1:os%=((USR&FFF4)AND&FF00)DIV256
1110 IFPAGE>&FFFFF:DIMX%LOCAL256:SYS"GetModuleFileName",0,X%,255:run$=$$X%:=@cmd$
1120 A%=(HIMEM>&FFFF)AND&900:A%=((PAGE>&9FFF)ANDA%)OR((&1400-PAGE)AND(A%=0)):IF?(TOP-3)ELSEA%=&B00
1130 A$=$(PAGE-&E00+A%):IFA%=0:run$=A$:SYS16TOA$,,A%:SYS72,"",A%:A$=MID$(A$,1+INSTR(A$+" "," ",1+INSTR(A$," "))):IFLENA$=0:A$=run$
1140 FORY%=-1TO0:A$=" "+A$:REPEATA$=MID$(A$,2):UNTILASCA$<>32
1150 IFY%:IFASCA$=34:A%=INSTR(A$,"""",2)+1 ELSE IFY%:A%=INSTR(A$+" "," ")
1160 IFY%:run$=MID$(A$,1-(ASCA$=34),A%-1+2*(ASCA$=34)):IFrun$<>"":A$=MID$(A$,A%+1)
1170 NEXT:=A$
1180 :
1190 DEFFNcl(l$,n%):IFl$="":A$=FNs(A$):IFASCA$=34:A%=INSTR(A$+" "" ",""" ",2):l$=MID$(A$,2,A%-2):A$=FNs(MID$(A$,A%+1)):=l$
1200 IFl$="":A%=INSTR(A$+" "," "):l$=LEFT$(A$,A%-1):A$=FNs(MID$(A$,A%+1)):=l$
1210 IFn%=0:IFl$<>"":A%=INSTR(A$,l$):IFA%:A$=FNs(LEFT$(A$,A%-1)+MID$(A$,INSTR(A$," ",A%)+1))+" ":=TRUE
1220 IFn%=0:IFl$<>"":=FALSE
1230 A%=INSTR(LEFT$(" ",ASCl$=32)+A$,l$):IFA%=0:=""
1240 A$=LEFT$(A$,A%-1)+FNs(MID$(A$,INSTR(A$," ",A%)+1))
1250 IFASCl$=32:l$=MID$(A$,A%):A$=LEFT$(A$,A%-1):=MID$(l$,1-(ASCl$=34),LENl$+2*(ASCl$=34))
1260 IFASCMID$(A$,A%,1)<>34:l$=MID$(A$,A%,INSTR(A$+" "," ",A%)-A%):A$=LEFT$(A$,A%-1)+MID$(A$,A%+LENl$+1):=l$
1270 l$=MID$(A$,A%+1,INSTR(A$+""" ",""" ",A%+1)-A%-1):A$=LEFT$(A$,A%-1)+MID$(A$,A%+LENl$+3):=l$
1280 DEFFNs(A$):IFLEFT$(A$,1)=" ":REPEATA$=MID$(A$,2):UNTILLEFT$(A$,1)<>" "
1290 IFRIGHT$(A$,1)=" ":REPEATA$=LEFT$(A$,LENA$-1):UNTILRIGHT$(A$,1)<>" "
1300 =A$