コード: 全て選択
Declare Function timeGetTime Lib "winmm.dll" () As Long
'#Strict
Const LineLength = 158 '一行のバイト数
Const xReSort=1000 'まとめてソートする行数
Dim SortIndex[xReSort] As Integer
Dim SortText[xReSort] As String
Dim SortKey[100]=[1,2,3,4,5,7,8,9,10,11,-1] As Char '列位置指定(-1で終了)
Dim StartTime As Long
Dim EndTime As Long
Dim xInFile As String
Dim xOutFile As String
Dim xWorkFile As String
Dim StrBuf As String
Dim i As Integer
' ---------------------------------------------
' バッファーの初期化
' ---------------------------------------------
StrBuf = ZeroString(LineLength)
For i=0 To xReSort
SortText = ZeroString(LineLength)
Next
' ---------------------------------------------
' 初期値を設定
' ---------------------------------------------
xInFile = "..\infile8000000.csv"
xOutFile = "OutPut.csv"
xWorkFile = "c:\tmp\marg"
kill xOutFile '旧ファイルを消す.
' ---------------------------------------------
' ソート&ファイル書込み
' ---------------------------------------------
StartTime = timeGetTime()
Open xOutFile For Append As #2
Field #2, LineLength 'バイト数
GigaSort( 0, xInFile )
Close #2
EndTime = timeGetTime()
MsgBox 0, Str$( EndTime - StartTime )&"ms"
End
'===============================================================================
' ファイルを用いたソート方法
'===============================================================================
Function GigaSort(xNo As Integer, xFileName As String)As Integer
Dim j As Integer
Dim Wk As String 'ワークファイル名
Dim FN As String '実行用ファイル名
Dim xCnt(9) As Integer '振り分け件数
j=SortKey[xNo]-1: If(xNo)Then Wk=xFileName Else Wk=xWorkFile
if(j>=0)Then 'ソート
Open xFileName For Input As #1: Field #1, LineLength
Open Wk + "0" For Output As #10: Field #10, LineLength
Open Wk + "1" For Output As #11: Field #11, LineLength
Open Wk + "2" For Output As #12: Field #12, LineLength
Open Wk + "3" For Output As #13: Field #13, LineLength
Open Wk + "4" For Output As #14: Field #14, LineLength
Open Wk + "5" For Output As #15: Field #15, LineLength
Open Wk + "6" For Output As #16: Field #16, LineLength
Open Wk + "7" For Output As #17: Field #17, LineLength
Open Wk + "8" For Output As #18: Field #18, LineLength
Open Wk + "9" For Output As #19: Field #19, LineLength
'
While (Eof(1)=0)
Get #1, -1, StrBuf
Select Case StrBuf[j]
case &h30: Put #10,-1,StrBuf: If(xCnt(0)<=xReSort)Then xCnt(0)=xCnt(0)+1
case &h31: Put #11,-1,StrBuf: If(xCnt(1)<=xReSort)Then xCnt(1)=xCnt(1)+1
case &h32: Put #12,-1,StrBuf: If(xCnt(2)<=xReSort)Then xCnt(2)=xCnt(2)+1
case &h33: Put #13,-1,StrBuf: If(xCnt(3)<=xReSort)Then xCnt(3)=xCnt(3)+1
case &h34: Put #14,-1,StrBuf: If(xCnt(4)<=xReSort)Then xCnt(4)=xCnt(4)+1
case &h35: Put #15,-1,StrBuf: If(xCnt(5)<=xReSort)Then xCnt(5)=xCnt(5)+1
case &h36: Put #16,-1,StrBuf: If(xCnt(6)<=xReSort)Then xCnt(6)=xCnt(6)+1
case &h37: Put #17,-1,StrBuf: If(xCnt(7)<=xReSort)Then xCnt(7)=xCnt(7)+1
case &h38: Put #18,-1,StrBuf: If(xCnt(8)<=xReSort)Then xCnt(8)=xCnt(8)+1
case &h39: Put #19,-1,StrBuf: If(xCnt(9)<=xReSort)Then xCnt(9)=xCnt(9)+1
End Select
Wend
Close #19
Close #18
Close #17
Close #16
Close #15
Close #14
Close #13
Close #12
Close #11
Close #10
Close #1
If(xNo)Then Kill(xFileName)
For j=0 To 9
FN=Wk + Str$(j)
If(xCnt(j))Then
If( xCnt(j)=1)Then
SortOut(FN) 'ソート必要なし
Else
If( xCnt(j)>xReSort)Then
GigaSort(xNo+1, FN) '再度分割
Else
MegaSort(xNo+1, FN, xCnt(j))
End If
Endif
End If
Kill(FN)
Next
Else
SortOut(xFileName)
End If
End Function
'-----------------------------------------------------------
' ソート結果の書込み
'-----------------------------------------------------------
Sub SortOut(xFileName As String)
Open xFileName For Input As #1: Field #1, LineLength
Field #1, LineLength 'バイト数
While (Eof(1)=0)
Get #1, -1, StrBuf
Put #2, -1, StrBuf
Wend
Close #1
End Sub
'===============================================================================
' 小規模ソート
'===============================================================================
Sub MegaSort(xNo As Integer, xFileName As String, nMax As Integer)
Dim i As Integer
Dim j As Integer
Dim k As Integer
Dim e As Byte
Dim w As Integer
'読込み
Open xFileName For Input As #1: Field #1, LineLength
For i=1 to nMax
Get #1, -1, SortText(i) As StrPtr: SortIndex=i
Next
Close #1
'
If(nMax>1)Then QuickSort( xNo, 1, nMax )
'書込み
For i=1 To nMax
Put #2, -1, SortText[SortIndex]
Next
End Sub
'----------------------------------------------------------
' クイックソート
'----------------------------------------------------------
Sub QuickSort( xNo As Integer, ByVal Kara As Long, ByVal Made As Long)
Dim i As Long
Dim j As Long
Dim w As Integer
Dim k As Integer
'
i=Kara : j=Made : k = SortIndex((i+j)\2) '基準k
Do
While KeyCheck( xNo, SortIndex(i) , k ): i=i+1: Wend
While KeyCheck( xNo, k , SortIndex(j) ): j=j-1: Wend
If (i <= j) Then
w = SortIndex(i): SortIndex(i) = SortIndex(j): SortIndex(j) = w
i=i+1 : j=j-1
End If
Loop Until (i > j)
If (Kara < j) Then QuickSort(xNo, Kara, j)
If (i < Made) Then QuickSort(xNo, i, Made)
End Sub
'----------------------------------------------------------
' 比較処理( L<R なら -1 )
'----------------------------------------------------------
Function KeyCheck( k As Integer, L As Integer, R As Integer ) As Long
Dim x As Long
Dim p1 As BytePtr
Dim p2 As BytePtr
p1=StrPtr(SortText(L))
p2=StrPtr(SortText(R))
Do
x=SortKey[k]-1: If( x<0 )Then Exit Function
If( p1[x] < p2[x] )Then Exit Do
If( p1[x] > p2[x] )Then Exit Function
k = k + 1
Loop
KeyCheck = -1
End Function