我正在尝试构建一个宏,该宏循环遍历工作簿中的每个工作表,并记录每个工作表所涉及的“帐单区域”以及每个工作簿中的一些其他信息。我的程序适用于第一个工作表,但不适用于第二个工作表。我正在搜索的是相同的标准化文本,但是Range.Find无法正常工作。这是代码:
Sub DenialsReport()
Dim heatWB, denialWB As Workbook
Dim heatWS, denialWS As Worksheet
Dim folderName, fileName, extName, wbName, billArea, postPeriod As String
Dim a, b, lastRow, countCol, volumeCol, startRow, billAreaRow, billAreaColumn, grandRow As Long
Dim postPeriodRange, billAreaRange, grandRange As Range
Set heatWB = ActiveWorkbook
Set heatWS = heatWB.Sheets("Denials")
postPeriod = InputBox("Please enter the current post period in this form: yyyymm")
Application.ScreenUpdating = False
folderName = heatWB.Sheets("Support->").Cells(19, 3).Value
fileName = heatWB.Sheets("Support->").Cells(20, 3).Value
extName = heatWB.Sheets("Support->").Cells(21, 3).Value
wbName = folderName + "\" + fileName + "." + extName
Set denialWB = Workbooks.Open(wbName)
b = 0
For Each denialWS In Worksheets
denialWS.Cells.UnMerge
Next denialWS
For Each denialWS In Worksheets
b = b + 1
denialWB.Sheets(b).Cells.UnMerge
lastRow = heatWS.Cells(Rows.Count, 1).End(xlUp).Row + 1
' find the bill area
Set billAreaRange = denialWB.Sheets(b).Range("A1:G10").Find(What:="For Bill Area: ", LookIn:=xlValues, LookAt:=xlPart, MatchCase:=False)
billAreaRow = billAreaRange.Row
billAreaColumn = billAreaRange.Column
' get the bill area
billArea = denialWB.Sheets(b).Cells(billAreaRow, billAreaColumn).Value
billArea = Replace(billArea, "For Bill Area: ", "")
billArea = Left(billArea, InStr(billArea, "(") - 1)
billArea = Trim(billArea)
' locate the count and amount columns along with the start and end of the rejection categories
Set postPeriodRange = d enialWB.Sheets(denialWS.Index).Range("A1:AZ15").Find(What:=postPeriod, LookIn:=xlValues, LookAt:=xlWhole)
countCol = postPeriodRange.Column
amountCol = countCol + 1
startRow = postPeriodRange.Row + 2
Set grandRange = denialWB.Sheets(denialWS.Index).Range("A:A").Find(What:="Grand Total", LookIn:=xlValues, LookAt:=xlWhole)
grandRow = grandRange.Row
' copy the information over to heatWS
For a = startRow To grandRow - 1
heatWS.Cells(lastRow, 1).Value = billArea
heatWS.Cells(lastRow, 2).Value = postPeriod
heatWS.Cells(lastRow, 3).Value = denialWS.Cells(a, 1).Value
heatWS.Cells(lastRow, 4).Value = denialWS.Cells(a, countCol).Value
heatWS.Cells(lastRow, 5).Value = denialWS.Cells(a, amountCol).Value
heatWS.Cells(lastRow, 6).Value = denialWS.Cells(a, amountCol).Value / denialWS.Cells(grandRow, amountCol).Value
lastRow = heatWS.Cells(Rows.Count, 1).End(xlUp).Row + 1
Next a
Next denialWS
denialWB.Close SaveChanges:=False
heatWS.Range("A:F").AutoFit
Application.ScreenUpdating = True
End Sub
此行出现问题:
Set billAreaRange = denialWB.Sheets(b).Range("A1:G10").Find(What:="For Bill Area: ", LookIn:=xlValues, LookAt:=xlPart, MatchCase:=False)
我还尝试过像这样对程序进行硬编码(值位于单元格C7中):
billArea = denialWB.Sheets(b).Cells(7,3).Value
我认为这意味着VBA无法识别单元格中存在值。但是,我可以实际进入单元格并进行编辑。任何帮助表示赞赏。谢谢。
答案 0 :(得分:0)
您的代码中有很多东西很容易对您不利。因此,除了建议您回答问题的建议之外,还有一些我认为会引起问题的常见问题。
单个通用声明行,例如
Dim folderName, fileName, extName, wbName, billArea, postPeriod As String
不不将类型String
分配给所有这些变量。在这种情况下,只有最后一个声明postPeriod As String
会声明类型String
的变量。所有其他变量默认为类型Variant
。标准做法是对每个变量使用单个行声明,每个变量都具有特定的类型。另外,您的代码看起来更干净,可以在首次使用它之前立即声明该变量/类型。这样,您不必滚动到顶部就可以知道类型是什么。所以:
Dim folderName As String
Dim fileName As String
Dim extName As String
...
接下来,read this explanation ActiveWorkbook
和ThisWorkbook
之间的差异。几乎总是它是您想要的后一种形式。所以你应该
Dim heatWB As Workbook
Set heatWB = ThisWorkbook
您有两个循环使用
For Each denialWS In Worksheets
...
Next denialWS
我在阅读此行时的假设是,您正在ActiveWorkbook中的工作表中循环。但是变量denialWS
表示您确实想遍历denialWB
的工作表。如果是这样,请使用
For Each denialWS In denialWB.Worksheets
...
Next denialWS
此外,在下一个循环中,您进入工作簿中的每个工作表,但通过设置b
变量(为什么?)并使用该变量在工作表中进行索引,也使事情变得混乱。 。因此,目前尚不清楚您要对哪张纸进行操作。 (为什么不使用denialWS
呢?)
最后回答涉及Find
的问题。如果您清除此处提到的问题,很容易会遇到这种情况,您的Find
问题将得到解决。但是,您也应该考虑失败的情况。因此,使用类似
Set billAreaRange = denialWS.Range("A1:G10").Find(What:="For Bill Area: ", _
LookIn:=xlValues, _
LookAt:=xlPart, _
MatchCase:=False)
If not billAreaRange Is Nothing Then
billAreaRow = billAreaRange.Row
billAreaColumn = billAreaRange.Column
... <the rest of your logic here>
Else
<raise an error or display a MsgBox here>
Exit For
End If
修复所有这些问题后,还应该修复您尝试过的硬编码测试。