アプリ版:「スタンプのみでお礼する」機能のリリースについて

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

A 回答 (2件)

[マルチなソート関数]


は、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
---------------------------------
    • good
    • 0
この回答へのお礼

素晴らしい回答です。
ありがとうございます。

お礼日時:2007/02/25 20:48

ソートキーとレコード(配列)Noを引数としてソート処理を


行うというのはどうでしょうか?
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています