VB6 ソートのやり方は知っていますが、構造体の定義が変わると対応できません。
ソート処理部分だけを共通関数にできますでしょうか?
Private Type Sort
strCol1 As String
intCol2 As Integer
sttCol3 As String
End Type
Private Sub A()
Dim typSort(3) As Sort
'ここに、構造体データ設定処理を記述
Call subSort(typSort(), typSortCopy)
End Sub
Private Sub subSort(typTaget() As Sort)
Dim lngOutLoop As Long
Dim lngCurent As Long
Dim lngInLoop As Long
Dim Min As Variant
Dim typSortCopy As Sort
For lngOutLoop = LBound(typTaget) To UBound(typTaget) - 1
Min = typTaget(lngOutLoop).strCol1
lngCurent = lngOutLoop
For lngInLoop = lngOutLoop + LBound(typTaget) + 1 To UBound(typTaget)
If typTaget(lngInLoop).strCol1 < Min Then
Min = typTaget(lngInLoop).strCol1
lngCurent = lngInLoop
End If
Next lngInLoop
typTagetCopy = typTaget(lngOutLoop)
typTaget(lngOutLoop) = typTaget(lngCurent)
typTaget(lngCurent) = typTagetCopy
Next lngOutLoop
End Sub
[マルチなソート関数]
は、VBだけの標準機能だけでは無理だと思います。
ましてや、構造体となると、もっと厳しいと思います。
どうしてもVBで「構造体+配列のソート」を可能にしたいというのであれば、
「構造体のサイズを固定で定める」という方法があります(処理はCと一緒)
Private Type Sort
strCol1 As String
intCol2 As Integer
sttCol3 As String
End Type
を
Private Type Sort
strCol1 As String * 10
intCol2 As Integer
sttCol3 As String * 12
End Type
などにする必要があります。こうすることにより、構造体のサイズが定まります。
(strCol1(20byte) + intCol2(2byte) + sttCol3(24byte) = Sort構造体は「計46byte」)
それをmemorycopyというAPI関数で、開始バイトから必要バイト数長を指定し、値を取得する必要があります。
しかし、、、そこまでして標準化する必要があるのか疑問を感じます。
んで、代替案ですが
構造体→クラス化
配列→Collection化
とする方法もあります。
これなら、ソートの標準関数も作りやすいかと思います。
以下に作ってみたものをそのまま載せます。
構成は
・Class1
・Class2
・Module1
です。
ソートロジックは、全てなめて見る方法を利用していますので、もっと効率よい方法をご存知であれば、それに置き換えてください。
---------------------------------
※1 Class1
Option Explicit
'他のクラスとの共通部
Public strCol1 As String
Public intCol2 As Integer
Public sttCol3 As String
'クラス1独自の変数
Public intHOGE1 As Integer
Private Sub Class_Initialize()
'sttCol3の規定値を設定
sttCol3 = "クラス1"
End Sub
---------------------------------
---------------------------------
※1 Class2
Option Explicit
'他のクラスとの共通部
Public strCol1 As String
Public intCol2 As Integer
Public sttCol3 As String
'クラス2独自の変数
Public strHOGE2 As String
Private Sub Class_Initialize()
'sttCol3の規定値を設定
sttCol3 = "クラス2"
End Sub
---------------------------------
---------------------------------
※1 Module1
Option Explicit
Sub Test()
Dim colClass1 As Collection
Dim colClass2 As Collection
Call クラス1のダミーデータ(colClass1)
Call クラス2のダミーデータ(colClass2)
Call クラスの内容デバッグ("ソート前", colClass1)
Call クラスの内容デバッグ("ソート前", colClass2)
Call subSort(colClass1)
Call subSort(colClass2)
Call クラスの内容デバッグ("ソート後", colClass1)
Call クラスの内容デバッグ("ソート後", colClass2)
End Sub
Sub subSort(ByRef p_col As Collection)
Dim l_colRet As Collection
Dim l_cls As Object
Dim l_clsMin As Object
Dim l_intMinID As Integer
Dim i As Integer
Set l_colRet = New Collection
Do Until (p_col.Count = 0)
'まずは先頭を基準
l_intMinID = 1
'先頭ははずしてループ
For i = 2 To p_col.Count
'基準のstrCol1と、ループのi番目のstrCol1との大小比較
If p_col(l_intMinID).strCol1 > p_col(i).strCol1 Then
'i番目の方が小さければ、それが基準
l_intMinID = i
End If
Next i
'一番小さい基準値のデータを登録
l_colRet.Add p_col(l_intMinID)
'引数のデータから削除
p_col.Remove l_intMinID
Loop
'結果の返却
Set p_col = l_colRet
End Sub
Public Sub クラスの内容デバッグ(ByVal p_strTytle As String, ByVal p_col As Collection)
Dim l_cls As Object
Dim i As Integer
For i = 1 To p_col.Count
Set l_cls = p_col(i)
Debug.Print p_strTytle & ":" & l_cls.sttCol3 & "の" & i & "番目: strCol1=" & l_cls.strCol1
Next i
End Sub
Private Sub クラス1のダミーデータ(ByRef p_col As Collection)
Dim l_cls As Class1
Set p_col = New Collection
Set l_cls = New Class1
l_cls.strCol1 = "3"
l_cls.intCol2 = 1
p_col.Add l_cls
Set l_cls = New Class1
l_cls.strCol1 = "2"
l_cls.intCol2 = 2
p_col.Add l_cls
Set l_cls = New Class1
l_cls.strCol1 = "1"
l_cls.intCol2 = 3
p_col.Add l_cls
Set l_cls = New Class1
l_cls.strCol1 = "0"
l_cls.intCol2 = 4
p_col.Add l_cls
End Sub
Private Sub クラス2のダミーデータ(ByRef p_col As Collection)
Dim l_cls As Class2
Set p_col = New Collection
Set l_cls = New Class2
l_cls.strCol1 = "2"
l_cls.intCol2 = 1
p_col.Add l_cls
Set l_cls = New Class2
l_cls.strCol1 = "1"
l_cls.intCol2 = 2
p_col.Add l_cls
Set l_cls = New Class2
l_cls.strCol1 = "3"
l_cls.intCol2 = 3
p_col.Add l_cls
End Sub
---------------------------------
お礼
素晴らしい回答です。 ありがとうございます。