VBA:如何最好地将三胞胎信息一起存储

时间:2020-07-08 08:23:18

标签: vba

我需要通过搜索存储在A列中的行来查找一些行。到目前为止,每次我需要这样做时,我都在a中调用了函数(FindRow)。新队。这意味着我的代码如下:

Option Explicit

Public fRowType As Long
Public fRowClosing As Long
Public fRowHPPlanDate As Long
Public fRowLoan As Long
Public fRowDoS As Long
Public fRowShare As Long
Public fRowInvestmentType As Long
Public fRowObjectNumber As Long
Public fRowObjectName As Long
Public fRowRisk As Long
Public fRowMacro As Long
Public fRowCountry As Long
Public fRowCity As Long
Public fRowConstruction As Long
Public fRowModernization As Long
Public fRowUsage As Long
Public fRowHPPlanYear As Long
Public fRowHP As Long
Public fRowInterest As Long
Public fRowBorrowed As Long
Public fRowLTV As Long
Public fRowEquity As Long
Public fRowSPVRev As Long
Public fRowSPVExp As Long
Public fRowNCF As Long
Public fRowIRR As Long
Public fRowIRRIM As Long
Public fRowCapRate As Long
Public fRowNOIAcq As Long
Public fRowLeased As Long
Public fRowRentalUnits As Long
Public fRowParking As Long
Public fRowTotalArea
Public fRowRent As Long
Public fRowNOI As Long
Public fRowWalt As Long
Public fRowPriceNet As Long
Public fRowExchange As Long
Public fRowCurrency As Long
Public fRowPriceGross As Long
Public fRowGIK As Long
Public fRowBook As Long
Public fRowMarketValue As Long
Public fRowMarketValuePerc As Long
Public fRowDeterminationMarketValue
Public fRowRepatriation As Long
Public fRowSalesPrice As Long

Sub Test()
    Call DefiningRows(ActiveSheet)
End Sub

Sub DefiningRows(ws As Worksheet) 
    fRowType = FindRow("Type", "A")
    fRowClosing = FindRow("Closing", "A")
    fRowHPPlanDate = FindRow("Holding Period Plan Date (BP)", "A")
    fRowLoan = FindRow("End of Loan", "A")
    fRowDoS = FindRow("Date of Sale", "A")
    fRowShare = FindRow("BVK-Share (%)", "A")
    fRowInvestmentType = FindRow("Investmet Type", "A")
    fRowObjectNumber = FindRow("Objectnumber", "A")
    fRowObjectName = FindRow("Objectname", "A")
    fRowRisk = FindRow("Risk Allocation", "A")
    fRowMacro = FindRow("Macro Allocation", "A")
    fRowCountry = FindRow("Country", "A")
    fRowCity = FindRow("City", "A")
    fRowConstruction = FindRow("Construction Year", "A")
    fRowModernization = FindRow("Modernization Year", "A")
    fRowUsage = FindRow("Main Usage", "A")
    fRowHPPlanYear = FindRow("Holding Period Plan Year (BP)", "A")
    fRowHP = FindRow("Holding Period Plan Year (BP)", "A") + 2
    fRowInterest = FindRow("Interest on debt (ytd.)", "A") + 1
    fRowBorrowed = FindRow("Borrowed Capital (Delta)", "A") + 1
    fRowLTV = FindRow("LTV (Delta)", "A") + 1
    fRowEquity = FindRow("Equity Investment (Delta)", "A") + 1
    fRowSPVRev = FindRow("SPV Revenues (ytd.)", "A") + 1
    fRowSPVExp = FindRow("SPV Expenses (ytd.)", "A") + 1
    fRowNCF = FindRow("NCF (ytd.)", "A") + 1
    fRowIRRIM = FindRow("IRR (IM)", "A")
    fRowIRR = FindRow("IRR (Forecast)", "A") + 1
    fRowCapRate = FindRow("CapRate (Acquisition)", "A") + 1
    fRowLeased = FindRow("Leased Area (m²)", "A") + 1
    fRowRentalUnits = FindRow("Rental Units", "A", PartOrWhole:=xlPart)
    fRowParking = FindRow("Parking Spaces", "A")
    fRowTotalArea = FindRow("Total Area (m²)", "A")
    fRowRent = FindRow("Contractual Rent", "A") + 1
    fRowNOI = FindRow("NOI (ytd.)", "A") + 1
    fRowWalt = FindRow("WALT", "A") + 1
    fRowPriceNet = FindRow("Purchase Price (net)", "A") + 1
    fRowExchange = FindRow("Exchange Rate", "A")
    fRowCurrency = FindRow("Currency", "A")
    fRowPriceGross = FindRow("Purchase Price (gross)", "A") + 1
    fRowGIK = FindRow("Total Costs (GIK)", "A") + 1
    fRowBook = FindRow("Book Value", "A") + 1
    fRowMarketValue = FindRow("Market Value", "A") + 1
    fRowMarketValuePerc = FindRow("Market Value", "A")
    fRowDeterminationMarketValue = FindRow("Determination of market value", "A")
    fRowSalesPrice = FindRow("Sales Price", "A")
    fRowRepatriation = FindRow("Equity Repatriation", "A")
End Sub

Function FindRow(ByVal searchTerm As String, ByVal col As String, Optional ws As Worksheet, Optional ByVal PartOrWhole As XlLookAt = xlWhole) As Long
    Dim searchRng   As Range            ' the range to search, based on the column passed to the function
    Dim foundCell   As Range            ' the found match
    
    If ws Is Nothing Then Set ws = ActiveSheet
    With ws
        Set searchRng = .Range(.Cells(1, col), .Cells(.Rows.Count, col).End(xlUp))
    End With
    
    Set foundCell = searchRng.Find(searchTerm, LookAt:=PartOrWhole)
    If Not foundCell Is Nothing Then
        FindRow = foundCell.Row
    Else
        MsgBox searchTerm & " couldn't be found. Macro will continue."
    End If
End Function

我的想法是用所有searchTerm组成一个数组并循环遍历。问题是,我意识到我每次都有三条信息:我要创建的变量的名称(例如fRowType searchTerm和我为此添加的行(0、1 ,2)。我可能想得太多了,但是我想不出什么来决定对我的问题进行搜索。有一篇文章使用Collection对象提出来。我尝试了一下,但很快意识到这可能不是一个好方法我什至没有用变量名创建数组,因为它看起来像这样:

Sub DefiningRows(ws As Worksheet) 'Loop -> is xlPart necessary? if so, separate array

    Dim fRowCollection As Collection
    Set fRowCollection = New Collection

    fRowCollection.Add Array("Type", "Closing", "Holding Period Plan Date (BP)", "End of Loan", "Date of Sale", "BVK-Share (%)", "Investmet Type", "Objectnumber", _
    "Objectname", "Risk Allocation", "Macro Allocation", "Country", "City", "Construction Year", "Modernization Year", "Main Usage", _
    "Holding Period Plan Year (BP)", "Holding Period Plan Year (BP)", "Interest on debt (ytd.)", "Borrowed Capital (Delta)", "Equity Investment (Delta)", _
    "SPV Revenues (ytd.)", "SPV Expenses (ytd.)", "NCF (ytd.)", "IRR (IM)", "IRR (Forecast)", "CapRate (Acquisition)", "NOI (Aquisition)", "Leased Area (m²)", _
    "Parking Spaces", "Total Area (m²)", "Contractual Rent", "NOI (ytd.)", "WALT", "Purchase Price (net)", "Exchange Rate", "Currency", "Purchase Price (gross)", _
    "Total Costs (GIK)", "Book Value", "Market Value", "Market Value", "Determination of market value", "Sales Price", "Equity Repatriation"), "searchTerm"

    fRowCollection.Add Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0), "additionalRow"

End Sub

这对我来说似乎不太可读,如果我或其他人要从数组中删除某些内容,他们将不得不遍历元素以确保删除additionalRow数组中的正确条目。似乎不实际。

什么是解决这个问题的好方法?

2 个答案:

答案 0 :(得分:2)

使用课程,您可以执行以下操作。

创建一个名为clsRow的新类,并为其提供三个简单的公共属性:

Snippet of class

Public Row As Long
Public SearchTerm As String
Public Name As String

现在,如果我将所有属性分配存储在sheet1的表中,例如:

Snippet of Table

我可以创建一个集合,遍历工作表数据,并用该数据逐行填充新类的许多实例,并将其添加到集合中:

Sub example()

Dim myRows As New Collection
Dim c As clsRow

For i = 2 To 11

    Set c = New clsRow

    ' next lines assign the new class properties based on the sheet values
    c.Name = Sheet1.Range("A" & i).Value2
    c.Row = Sheet1.Range("B" & i).Value2
    c.SearchTerm = Sheet1.Range("C" & i).Value2

    ' next line adds this particular instance of the class
    ' to the collection with a KEY based on the class' name (can use any property)
    myRows.Add c, c.Name ' 
Next i

' I can now use any key to call on any member of the collection
MsgBox myRows("e").SearchTerm
' e.g. will produce "Look 5"
MsgBox myRows("b").Row
' e.g. will produce "10"

End Sub
简而言之,您将所有数据定义放在易于维护的位置(隐藏的工作表?!而不是硬编码),通过循环遍历该工作表来填充自定义类的集合,然后剩下一大堆数据更容易随叫随到。

您可以以这种方式建立无限的方式,祝您好运,玩得开心!

答案 1 :(得分:1)

您可以在自定义类中编写一个函数,使您可以以更加整洁的方式对属性进行硬编码:

我的班级现在看起来像这样:

Public property1 As Long
Public property2 As String
Public property3 As String

Public Function Add(param1 As Long, param2 As String, param3 As String, ByRef col As Collection) As Collection
  property1 = param1
  property2 = param2
  property3 = param3
  col.Add Me, param2
  Set Add = col
End Function

它包含四个参数-我要设置的三个属性以及我要向其中添加类本身的集合。请注意,col.Add Me, param2使用Meparam2property2(此时相同)作为键来添加类本身。

然后我可以编写一个函数,在其中存储并返回所有对齐在一起的属性,如下所示:

Function GetMyClasses() As Collection

Dim returnCollection As New Collection

Dim f1 As New Class1: f1.Add 10, "Type", "A", returnCollection
Dim f2 As New Class1: f2.Add 20, "Closing", "A", returnCollection
Dim f3 As New Class1: f3.Add 30, "Etc", "B", returnCollection

set GetMyCollection = returnCollection

End Function

f1f2的命名在这里无关紧要,一旦返回了集合,您就无需处理类的名称,您只需处理对象的每个实例中的属性即可。集合中的类:

Sub TestMe()
Dim aCollection As New Collection
Set aCollection = GetMyClasses
    MsgBox aCollection("Type").property3
End Sub

同样,您可以通过多种方法来实现它并编写自己的函数,以提供所需的确切语法,但是我希望这可以向您展示一些您可以使用类做的更酷的事情!