2

.cpp ファイル名のリストを含む 1 つの列と、テスト ケースを表す別の列があります。テスト ケースの文字列に一致するシート内のすべての行を検索し、その行からファイル名を出力したいと考えています。

column 1        column2 
--------       ------------    
file1.cpp      testcase1   
file2.cpp      testcase1   
file3.cpp      testcase3    
...             .......    
....            .......     

したがって、最終的には次のような出力が必要です。

Testcase1   Testcase2     
file4.cpp   file5.cpp    
file9.cpp   file8.cpp     
file5.cpp   file13.cpp  

vbaコードは次のとおりです。

Function fileToTest(Search_string As String, _
Search_in_col As Range)

Dim result As String   
Dim i As Long   
Dim j As Long   
Dim rArray(20) As String    
Dim rCnt As Long   
Dim rTmp As String   
Dim found As Long   
Dim testCases, Value As Variant   
Dim currentRow As Long    
Dim fCnt As Long    

  For i = 1 To Search_in_col.Count 'search each test case column    
     testCases = Split(Search_in_col.Cells(i, 1), ";")    
     For Each Value In testCases    
         If Search_string = Value Then    

        ActiveCell.Value = Search_in_col.Cells(i, 2).Value    
         ' write the next row after active cell. not sure how to do this
        End If   
      Next Value   
   Next i   


End Function   

ActiveCell.Value に書き込もうとすると関数が失敗します

4

1 に答える 1

0

あなたが直面している問題は、コメントによると、ユーザー定義関数が必要ですが、ワークシートを変更しようとすることです。これは不可能です。UDF のアーキテクチャでは、ワークシートに何も変更することはできず、関数で値を返すだけであり、それが表示されるためです。また、UDF では、通常、パラメーターとして渡されたセル以外のセルの値を読み取ることは許可されていません。そうしないと、Excel がどこかに循環参照があると判断します。

したがって、次の 3 つのオプションが表示されます。

  1. UDF を変更する
  2. 1 回のラッシュですべてのセルを埋めるマクロを作成する
  3. Excel の数式のみを使用する

詳細は次のとおりです。

1. UDF を変更する

A1 に「testcase1」と入力すると仮定すると、次のように呼び出すことができる UDF を作成します。

=FileToTestCase(A1,1,ソースシート!A2:A100,ソースシート!B2:B100)

UDF の VBA 定義は次のようになります。

Public Function FileToTestCase(sTestCaseName as String, iElementNumber as Integer, _
    rngFileNames as Range, rngTestcases as Range) as String
    CodeToFigure out the iElementNumer_th entry for sTestCaseName
    FileToTestCase = YourResult
 End Function

ただし、このアプローチは、ソース リストを毎回解析する必要があるため、非常に非効率的です。最初の呼び出しで初期化し、後で使用する内部のモジュール全体の変数を使用して、これを高速化できますが、変更を検出するように注意する必要があります。または、1 つの大きな配列数式で実行します。ただし、どちらのアプローチもかなりの労力を要します。

2.一度にすべてのセルを埋めるマクロを作成する

UDF の代わりに、1 つのラッシュですべてのセルを設定する 1 つのマクロがあります。コンテンツを自動的に更新する場合は、ソース データが変更されるたびに Worksheet_Change イベントからマクロを呼び出します。

このコードはこれを行う必要があります:

Sub FillTestcases(rngFiles As Range, rngTestcases As Range, rngStartResult As Range)
    Dim d As New Scripting.Dictionary
    Dim lRow As Long
    Dim sTestCase As Variant
    Dim sFile As Variant
    Dim rngResult As Range
    Const csSeparator As String = "|"

    For lRow = 1 To rngFiles.Rows.Count
        sTestCase = rngTestcases(lRow, 1).Value
        sFile = rngFiles(lRow, 1).Value
        If d.Exists(sTestCase) Then
            d(sTestCase) = d(sTestCase) & csSeparator & sFile
        Else
            d.Add sTestCase, sFile
        End If
    Next

    Set rngResult = rngStartResult
    For Each sTestCase In d.Keys
        rngResult.Value = sTestCase
        rngResult.Font.Bold = True
        lRow = 1
        For Each sFile In Split(d(sTestCase), csSeparator)
            rngResult.Offset(lRow) = sFile
            lRow = lRow + 1
        Next sFile
        Set rngResult = rngResult.Offset(, 1)
    Next sTestCase
End Sub

Dictionary クラスを使用するには、Microsoft Scripting Runtimeへの参照を追加する必要があることに注意してください。また、このコードは重複を統合しないため、微調整が必​​要になる場合があることに注意してください。

3. Excel の数式のみを使用する

ファイル名が A1:A10 にあり、テスト ケースが B1:B10 にあり、テスト ケース名のリストが F 列から始まる行 1 にあると仮定して、F2 で次の式を使用します。

=IFERROR(INDEX($A$1:$A$10,-INT((LARGE(($B$1:$B$10=F$1)-ROW($B$1:$B$10)/10000,ROW(F1)))) -1)*10000)),"")

配列数式なので、Ctrl--Shiftで入力しEnterます。

チッ!

于 2013-02-14T23:13:14.360 に答える