我需要通过搜索存储在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
数组中的正确条目。似乎不实际。
什么是解决这个问题的好方法?
答案 0 :(得分:2)
使用课程,您可以执行以下操作。
创建一个名为clsRow
的新类,并为其提供三个简单的公共属性:
Public Row As Long
Public SearchTerm As String
Public Name As String
现在,如果我将所有属性分配存储在sheet1的表中,例如:
我可以创建一个集合,遍历工作表数据,并用该数据逐行填充新类的许多实例,并将其添加到集合中:
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
使用Me
以param2
或property2
(此时相同)作为键来添加类本身。
然后我可以编写一个函数,在其中存储并返回所有对齐在一起的属性,如下所示:
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
f1
,f2
的命名在这里无关紧要,一旦返回了集合,您就无需处理类的名称,您只需处理对象的每个实例中的属性即可。集合中的类:
Sub TestMe()
Dim aCollection As New Collection
Set aCollection = GetMyClasses
MsgBox aCollection("Type").property3
End Sub
同样,您可以通过多种方法来实现它并编写自己的函数,以提供所需的确切语法,但是我希望这可以向您展示一些您可以使用类做的更酷的事情!