VBA Userform更新Inventory工作表行错误问题求助
在VBA用户窗体中,向Incomes工作表录入新销售数据的流程正常:用户先从Combobox1选择艺术家,Combobox2自动加载该艺术家在Inventory表中的作品,销售数据可正常写入Incomes表。
后续调用GetRowNumber函数时,需在Inventory表中同时匹配指定艺术家与售出作品,返回对应行号并将该行的Sold列设为"Y"。目前已成功匹配到目标行号,但执行更新操作时错误修改了目标行下方第2行的内容。尝试将Range起始位置改为A1并将传入的行号减1后可正常工作,但不确定该方案是否规范,寻求正确的代码修正建议。
原代码
Private Sub GetRowNumber() Dim Found As Range, Firstfound As String Dim rngSearch As Range Dim ArtistVal As String ArtistVal = ddlArtist.Value Dim ArtVal As String ArtVal = ddlArtwork.Value Set rngSearch = shInventory.Range("C:C") Set Found = rngSearch.Find(what:=ArtVal, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, _ SearchDirection:=xlNext, MatchCase:=False) If Not Found Is Nothing Then Firstfound = Found.Address Do If Found.EntireRow.Range("B1").Value = ArtistVal Then Exit Do 'Match found Set Found = rngSearch.FindNext(after:=Found) If Found.Address = Firstfound Then Set Found = Nothing Loop Until Found Is Nothing End If If Not Found Is Nothing Then 'MsgBox "Found `ArtVal` at row " & Found.row Call WriteSoldUpdatateToInvetory(Found.row) Else MsgBox "Nothing matched both criteria. ", , "No Match Found" End If End Sub Public Sub WriteSoldUpdatateToInvetory(ByVal m_currentRow As Long) With shInventory.Range("A2").offset(m_currentRow) .Cells(1, 8).Value = "Y" End With End Sub
问题原因
原WriteSoldUpdatateToInvetory方法的逻辑错误:shInventory.Range("A2").Offset(m_currentRow) 是从A2单元格开始向下偏移m_currentRow行。但m_currentRow本身就是目标行的行号(比如目标行是第5行,m_currentRow=5),偏移后实际指向A2+5行=第7行,这就是为什么会修改目标行下方第2行的原因。
规范修正方案
方案1:直接通过行号+列号定位(最简洁规范)
直接使用Cells方法,通过行号和列号(Sold列为第8列,即H列)定位目标单元格:
Public Sub WriteSoldUpdatateToInvetory(ByVal m_currentRow As Long) ' 直接定位目标行的H列单元格 shInventory.Cells(m_currentRow, 8).Value = "Y" End Sub
方案2:使用Range+Offset(你的修改是规范可行的)
如果坚持使用Range+Offset的写法,从A1开始偏移m_currentRow-1行是正确的,因为A1是第1行,偏移n行后就是第n+1行,因此m_currentRow-1的偏移量对应目标行号:
Public Sub WriteSoldUpdatateToInvetory(ByVal m_currentRow As Long) With shInventory.Range("A1").Offset(m_currentRow - 1) .Cells(1, 8).Value = "Y" End With End Sub
额外代码优化建议
GetRowNumber中Found.EntireRow.Range("B1")可以简化为Found.Offset(0, -1)(因为Found在C列,向左偏移1列就是B列),代码更简洁高效:
If Found.Offset(0, -1).Value = ArtistVal Then Exit Do
内容的提问来源于stack exchange,提问作者user3544580

