[リストへもどる]
一括表示

投稿時間:2003/01/24(Fri) 18:51
投稿者名:秋風
Eメール:
URL :
タイトル:
動的配列を返すプロシージャについて
こんばんは。

動的配列を返すプロシージャついての質問なのですが、現在、VB5.0を使用
している為、Split関数が使えません。ですので、モジュールで、Split関数
を作成したのですが、その際、分割した後、配列を返したいのですができません。
コードとしましては、
本プログラム
    Line Input #intfreefileno, TimeList ←ここに、A,B,C,…とデータがある
    strTimeList() = split(TimeList)
    …

モジュール
Function split(Time As String) As String() ←ここでエラー

    Dim intcheck As Integer
    Dim strtime(1 To 30) As String ←30個以内には、データは収まる
    i = 1

    Do
        intlen = Len(Time)
        intcheck = InStr(Time, ",")
        
        If intcheck <> 0 Then
            strtime(i) = Mid(Time, 1, intcheck - 1)
            i = i + 1
        End If
        
        Time = Mid(Time, intcheck, intlen - intcheck)
        
    Loop Until (intcheck = 0)
    
    split = strtime

End Function

と、String()の()でエラーが出てしまいます。VB6.0だと使用可能
とありましたが、VB5.0では不可能でしょうか?調べてはみたものの
解決しませんでした。(;_;)
お分かりの方教えて下さい。お願いします。m(_ _)m

投稿時間:2003/01/24(Fri) 19:08
投稿者名:nanashi
Eメール:
URL :
タイトル:
Re: 動的配列を返すプロシージャについて
Variant型で返してみたらどうでしょう?

投稿時間:2003/01/24(Fri) 20:28
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re: 動的配列を返すプロシージャについて
http://www001.upp.so-net.ne.jp/shige-3peace/ さんのところの

下記のサンプルを使わせてもらったらどうですか?
http://www001.upp.so-net.ne.jp/shige-3peace/VB_Freak/lzh/VB6toVB5.zip

とりあえず、ちょっといじって見ました。

Private Sub Command1_Click()
    Dim i As Integer
    Dim MyVar As Variant
    MyVar = split("abc,defgh,ijklm")
    For i = LBound(MyVar) To UBound(MyVar)
        Debug.Print MyVar(i)
    Next i
End Sub

Function split(Time As String) As Variant      '←ここでエラー
    Dim intcheck As Integer
    Dim strtime() As String          '←30個以内には、データは収まる
    Dim i As Long
    Dim intlen As Long
    i = 0
    Do
        intlen = Len(Time)
        intcheck = InStr(Time, ",")
        ReDim Preserve strtime(i) As String
        If intcheck <> 0 Then
            strtime(i) = Mid(Time, 1, intcheck - 1)
            Time = Mid(Time, intcheck + 1, intlen - intcheck)
            i = i + 1
        End If
        If intcheck = 0 And Len(Time) > 0 Then
            strtime(i) = Time
        End If
    Loop Until (intcheck = 0)
    split = strtime
End Function

投稿時間:2003/01/25(Sat) 14:39
投稿者名:takk
Eメール:
URL :
タイトル:
Re: 動的配列を返すプロシージャについて
手元にVB5.0がないんですが……。
下記のソースで試してみてください。
秋風さんのソースではエラーが多く、また汎用性に欠けるので手直ししました。
ちなみに戻り値をString()にするとエラー出る、とのことですがVB6.0では問題なく動いています。
もしダメそうならnanashiさんの意見通り、戻り値をVariant型で指定してみてください。


'使う時はこんな感じで
strTimeList() = split(TimeList, ",")

'ファンクション
Private Function Split(ByVal Data As String, Optional ByRef Demiliter As String = " ") As String()
    Dim lCnt&, lPos&, lLen As Long
    Dim sBuff() As String
    
    '文字列が指定されていない時は要素なしの配列を返す
    If Len(Data) = 0 Then
        Split = Array()
        Exit Function
    End If
    
    'デミリタの長さを取得
    lLen = Len(Demiliter)
    
    Do
        '次のデミリタの位置を取得
        lPos = InStr(Data, Demiliter)
        
        '配列に追加
        If lPos > 0 Then
            ReDim Preserve sBuff(lCnt)
            
            sBuff(lCnt) = Left$(Data, lPos - 1)
            Data = Mid$(Data, lPos + lLen)
            
            lCnt = lCnt + 1
        Else
            ReDim Preserve sBuff(lCnt)
            
            sBuff(lCnt) = Data
            Data = vbNullString
        End If
    Loop While Len(Data) > 0
    
    '結果を返す
    Split = sBuff
End Function

投稿時間:2003/01/25(Sat) 16:20
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re^2: 動的配列を返すプロシージャについて
> ちなみに戻り値をString()にするとエラー出る、とのことですがVB6.0では問題なく動いています。
配列を戻り値として返せるようになったのは、VB6からなのです。(^^;
http://www.asia.microsoft.com/japan/developer/library/default.asp?URL=/japan/developer/library/vbcon98/vbmscwhatsnewinlanguagefeaturesvb98.htm


> もしダメそうならnanashiさんの意見通り、戻り値をVariant型で指定してみてください。
そうですね。VB5では、戻り値をVariantにして対処する方法が、一般的だと思います。
Variant型には、配列を格納する事ができますので、今回のような「String配列」を
返すような目的には充分でしょう。

ただし、この方法で返せる配列は、「Variantに格納できるデータ型の配列」に限られます。

StringやLongなどの配列であれば問題はないのですが、VB5のユーザー定義型の場合は、
Variantに格納することができませんので、VB6でいうところの

  Option Explicit
  Public Type TEST
    aa As Long
  End Type
  Public Function Proc() As TEST()
    Dim a(1) As TEST
    a(0).aa = 123
    a(1).aa = 456
    Proc = a
  End Function
  Private Sub Main()
    Dim T() As TEST
    T = Proc()
    Debug.Print T(0).aa + T(1).aa
  End Sub

というコードを、
  Public Function Proc() As Variant
    Dim a(1) As TEST
    a(0).aa = 123
    a(1).aa = 456
    Proc = a
  End Function
のようにして対処する事は、残念ながらできません。


このような場合は、戻り値のかわりに引数を使って
渡すようにする事で、一応は対処する事ができます。

  Public Sub Proc(ByRef a() As TEST)
    ReDim a(1)
    a(0).aa = 123
    a(1).aa = 456
  End Sub
  Private Sub Main()
    Dim T() As TEST
    Call Proc(T)
    Debug.Print T(0).aa + T(1).aa
  End Sub

投稿時間:2003/01/25(Sat) 17:38
投稿者名:秋風
Eメール:
URL :
タイトル:
Re^3: 動的配列を返すプロシージャについて
>花ちゃんさん。takkさん。魔界の仮面弁士さん。nanashiさん。

回答ありがとうございます。後、返事が遅れて申し訳
ありませんでした。

やはりVB6.0からの機能でしたか。みなさんが教えてくれた
事を参考に作成していきます。また、のちほど結果報告したい
と思います。ありがとうございました。m(_ _)m

投稿時間:2003/01/27(Mon) 12:04
投稿者名:秋風
Eメール:
URL :
タイトル:
Re^3: 動的配列を返すプロシージャについて
こんにちは。

>花チャンさん。
今回は、花ちゃんさんのコードを参考させていただきました。
ありがとうございます。m(_ _)m
作成しましたので、情けないプログラムながら結果を載せておきます。

フォーム部分
Option Explicit
Dim intcheck As Integer
Dim strtime As String
Dim varTimeList As Variant
Dim strList(1 To 8, 19) As String
Dim j As Long   'ループカウンタ

Private Sub Form_Load()

    Dim k As Long   '1次元配列カウンタ
    Dim l As Long   '2次元配列カウンタ
    
    k = 1  
    intfreefileno = FreeFile
    Open App.Path & "\稼働報告書.txt" For Input As #intfreefileno
    ↑あらかじめデータだけ入ってる(8行)テキストファイルを呼び出し。
  (このファイルは、値は変化しません。)

    For j = 1 To 8   '8行分を配列に格納
        Line Input #intfreefileno, strTimeList
        varTimeList = split(strTimeList)
        
        For i = 1 To 18
            strList(k, l) = varTimeList(l) ←ちょっと値の格納の仕方が分からない
                       為、初心者風になってしまいました。(;_:)
            l = l + 1
        Next i
        
        k = k + 1
        l = 0
    Next j
    
    Close #intfreefileno
End Sub

標準モジュール部分
Function split(Time As String) As Variant

    Dim intcheck As Integer
    Dim intlen As Integer
    Dim strtime() As String
    
    i = 0
    
    Do
        intlen = Len(Time)
        intcheck = InStr(Time, ",")
        ReDim Preserve strtime(i) As String
        
        If intcheck <> 0 Then
            strtime(i) = Mid(Time, 1, intcheck - 1)
            Time = Mid(Time, intcheck + 1, intlen - intcheck)
            i = i + 1
        End If
    Loop Until (intcheck = 0) ←最後のデータは、全て"END"が入っている
               為、格納はしていません。

    split = strtime
End Function

と自分で改造した部分は素人なプログラムになってしまいましたが、とりあえず
動いているので、これを使用していこうかと思っています。特に、

For i = 1 To 18
    strList(k, l) = varTimeList(l) 
  l = l + 1
Next i
        
が、いきなり2次元配列に格納できない為、いちいち入れなおす方法にしか
できずに、四苦八苦しています。また、良い方法が無いか考えていきます。

>nanashiさん。
Variant型に致しました。回答ありがとうございます。m(_ _)m

>takkさん。
回答いただき大変感謝しております。ちょっとStringで返すのは、
VB5ではできない為、今回は、上記に書いた通りに致しました。
大変申し訳ありません。m(_ _)m

>魔界の仮面弁士さん。
教えていただきましたHPを確認したところ、大変参考になりました。
ありがとうございました。m(_ _)m