寻求含空行的3张工作表的VBA LastRow解决方案及自动ID生成
解决方案
原代码问题分析
- 未声明
ws1、ws2变量,直接引用导致另外两个工作表写入失败 - 开头的空行查找循环逻辑错误(
LastRow未初始化就使用),完全无效 - 复用同一个
LastRow变量,容易造成混淆和赋值错误 - 未处理空字段场景,导致覆盖已有数据或写入错误行
修正后的完整代码
Sub CommandButton1_Click() ' 声明工作表变量 Dim wsGuests As Worksheet Dim wsDiverDetails As Worksheet Dim wsBookTravel As Worksheet ' 声明各表最后行变量及统一ID变量 Dim lastRowGuests As Long Dim lastRowDiver As Long Dim lastRowTravel As Long Dim nextID As Long ' 绑定工作表对象 Set wsGuests = ThisWorkbook.Sheets("Guests") Set wsDiverDetails = ThisWorkbook.Sheets("Diver details") Set wsBookTravel = ThisWorkbook.Sheets("Book and Travel") ' 获取各表最后数据行(A列) lastRowGuests = wsGuests.Cells(wsGuests.Rows.Count, "A").End(xlUp).Row lastRowDiver = wsDiverDetails.Cells(wsDiverDetails.Rows.Count, "A").End(xlUp).Row lastRowTravel = wsBookTravel.Cells(wsBookTravel.Rows.Count, "A").End(xlUp).Row ' 生成统一ID(取三个表中最大ID加1,假设ID在A列) nextID = Application.Max( _ IIf(lastRowGuests = 1 And wsGuests.Range("A1") = "", 0, wsGuests.Range("A" & lastRowGuests)), _ IIf(lastRowDiver = 1 And wsDiverDetails.Range("A1") = "", 0, wsDiverDetails.Range("A" & lastRowDiver)), _ IIf(lastRowTravel = 1 And wsBookTravel.Range("A1") = "", 0, wsBookTravel.Range("A" & lastRowTravel)) _ ) + 1 ' 写入Guests表数据(包含ID) With wsGuests.Cells(lastRowGuests + 1, 1) .Value = nextID .Offset(0, 1).Value = Me.tbFirst_name.Value .Offset(0, 2).Value = Me.tbLast_name.Value ' 继续添加其他字段... End With ' 写入Diver details表数据(包含ID) With wsDiverDetails.Cells(lastRowDiver + 1, 1) .Value = nextID .Offset(0, 1).Value = Me.tbCert_level.Value .Offset(0, 2).Value = Me.tbNod.Value ' 继续添加其他字段... End With ' 写入Book and Travel表数据(包含ID) With wsBookTravel.Cells(lastRowTravel + 1, 1) .Value = nextID .Offset(0, 1).Value = Me.tbDep_date.Value .Offset(0, 2).Value = Me.tbLeave_date.Value ' 继续添加其他字段... End With ' 清空用户窗体输入框(可选) Me.tbFirst_name.Value = "" Me.tbLast_name.Value = "" Me.tbCert_level.Value = "" Me.tbNod.Value = "" Me.tbDep_date.Value = "" Me.tbLeave_date.Value = "" ' 清空其他字段... End Sub
关键改进说明
- 独立变量管理:为每个工作表单独定义
lastRow变量,避免复用导致的赋值混乱 - 正确工作表引用:直接使用已绑定的工作表对象,不再引用未声明的
ws1/ws2 - 统一ID生成逻辑:
- 判断各表首行是否为空(避免空表时取到无效值)
- 取三个表中最大ID值加1,确保ID唯一且连续
- 安全写入逻辑:使用
Offset定位列,确保写入新行(lastRow + 1),不会覆盖已有数据 - 空字段处理:即使输入框为空,也会写入新行而非覆盖旧数据;若需跳过空字段,可添加
If Not IsEmpty(Me.xxx.Value) Then判断
补充说明
如果每个工作表需要独立ID(而非统一ID),可修改ID生成逻辑为:
' Guests表独立ID nextIDGuests = IIf(lastRowGuests = 1 And wsGuests.Range("A1") = "", 1, wsGuests.Range("A" & lastRowGuests) + 1) ' Diver details表独立ID nextIDDiver = IIf(lastRowDiver = 1 And wsDiverDetails.Range("A1") = "", 1, wsDiverDetails.Range("A" & lastRowDiver) + 1) ' Book and Travel表独立ID nextIDTravel = IIf(lastRowTravel = 1 And wsBookTravel.Range("A1") = "", 1, wsBookTravel.Range("A" & lastRowTravel) + 1)
然后在写入对应表时使用各自的nextID即可。
内容的提问来源于stack exchange,提问作者ManfromSDS
相关产品推荐
相关产品推荐

