excel - Excel VBA - 如果填写了其他单元格,则不允许空白
问题描述
我正在寻找添加到下面的代码。我有一个电子表格,最终用户可以在其中列出任务列表并为每个任务分配小时数,然后点击一个按钮并将其提交给任务跟踪器。
我要防止的是最终用户输入任务并忘记输入时间,当提交给跟踪器时,我们的总数会因为空白而关闭。
在下面的代码中,您会看到它在 D 列中查找模型,在 E 列中查找模型时间,然后在 I 列中查找图纸,在 J 列中查找绘图时间。但我不确定如何说“如果 D10 中有数据而 E10 中没有数据,和/或如果 I3 中有数据但 J3 中没有数据,则显示错误消息“任务没有分配小时数。”
任何帮助,将不胜感激!!
Function compareCols(rng As Range) As String
Dim rngC1 As Range, cel As Range, i As Long
Set rngC1 = rng.Columns(1).SpecialCells(xlCellTypeConstants)
For Each cel In rngC1.Cells
If cel.Value <> "" And cel.Offset(0, 1) = "" Then
compareCols = "No hours in " & cel.Offset(0, 1).Address: Exit Function
End If
Next cel
compareCols = "OK"
End Function
Sub CAD_Task_Entry()
Dim InstalDesc As String
Dim Model As Range
Dim Drawing As Range
Dim Index As Long
Dim m As Long, n As Long
Application.ScreenUpdating = False
'Copy data from the input screen to the task list.
Sheets("Task Entry Form").Select
InstalDesc = Range("D3")
Set Model = Range("D5", Cells(Rows.Count, "D").End(xlUp)).Resize(, 2)
Set Drawing = Range("I5", Cells(Rows.Count, "I").End(xlUp)).Resize(, 2)
Index = Range("Q2")
With Sheets("Task List")
'get first row
n = .Range("D:X").Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
If n = 3 Then n = 4 Else n = n + 2
'color first row
.Range("A" & n & ":Z" & n).Interior.Color = 15189684
.Cells(n, "D") = InstalDesc & " Summary"
'verify hours are filled in on tasks
Dim strOK As String
strOK = compareCols(Model)
If strOK <> "OK" Then MsgBox strOK: Exit Sub
strOK = "": strOK = compareCols(Drawing)
If strOK <> "OK" Then MsgBox strOK: Exit Sub
If Model.Rows.Count > 1 Then
Model.Columns(1).SpecialCells(xlCellTypeConstants).Copy
.Cells(n + 1, "E").PasteSpecial xlPasteValues
Model.Columns(2).SpecialCells(xlCellTypeConstants).Copy
.Cells(n + 1, "Q").PasteSpecial xlPasteValues
Else
Model.Columns(1).Copy
.Cells(n + 1, "E").PasteSpecial xlPasteValues
Model.Columns(2).Copy
.Cells(n + 1, "Q").PasteSpecial xlPasteValues
End If
If Drawing.Rows.Count > 1 Then
Drawing.Columns(1).SpecialCells(xlCellTypeConstants).Copy
.Cells(n + Model.Rows.Count + 1, "F").PasteSpecial xlPasteValues
Drawing.Columns(2).SpecialCells(xlCellTypeConstants).Copy
.Cells(n + Model.Rows.Count + 1, "Q").PasteSpecial xlPasteValues
Else
Drawing.Columns(1).Copy
.Cells(n + Model.Rows.Count + 1, "F").PasteSpecial xlPasteValues
Drawing.Columns(2).Copy
.Cells(n + Model.Rows.Count + 1, "Q").PasteSpecial xlPasteValues
End If
'get last row after inserting data
m = .Range("D:X").Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
'create formulas
'add backchecking and forumla
.Cells(m + 1, 7) = "Backchecking"
.Cells(m + 1, 17) = "=SUM(Q" & n + 1 & ":Q" & m & ")/2"
'projected hours
.Cells(n, "Q") = "=SUM(Q" & n + 1 & ":Q" & m + 1 & ")"
'actual hours
.Cells(n, "S") = "=SUM(S" & n + 1 & ":S" & m + 1 & ")"
'install % complete
.Cells(n, "U") = "=SUMPRODUCT(V" & n + 1 & ":V" & m + 1 & "+X" & n + 1 & ":X" & m + 1 & ",R" & n + 1 & ":R" & m + 1 & ")/SUM(R" & n + 1 & ":R" & m + 1 & ")"
.Cells(n, "U").NumberFormat = "0%"
'weight
.Cells(n + 1, "R") = "=Q" & n + 1 & "/$Q$" & n
.Cells(n + 1, "R").AutoFill Destination:=.Range("R" & n + 1 & ":R" & m + 1)
'formatting weight
With Range("R" & n & ":R" & m).Select
Selection.NumberFormat = "0.00"
End With
'create dropdowns
'assigned to
With .Range("T" & n & ":T" & m + 1).Validation
.Delete
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1:="=Summary!$H$3:$H$14"
End With
'stages
Sheets("Task List").Select
For i = n + 1 To m + 1
If Cells(i, 5).Value <> "" Then
.Range("W" & i).Validation.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1:="=Data!$B$4:$B$9"
.Cells(i, "V") = "=IFERROR(VLOOKUP(W" & i & ",Data!$B$4:$C$9,2,FALSE),"""")"
.Range("W" & i).Value = "Not Started"
.Range("T" & i).Value = Sheets("Summary").Range("H4").Value
.Range("S" & i).Value = "0"
End If
If Cells(i, 6).Value <> "" Then
.Range("Y" & i).Validation.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1:="=Data!$E$4:$E$15"
.Cells(i, "X") = "=IFERROR(VLOOKUP(Y" & i & ",Data!$E$4:$F$15,2,FALSE),"""")"
.Range("Y" & i).Value = "Not Started"
.Range("T" & i).Value = Sheets("Summary").Range("H4").Value
.Range("S" & i).Value = "0"
End If
If Cells(i, 7).Value <> "" Then
.Range("Y" & i).Validation.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1:="=Data!$B$15:$B$16"
.Cells(i, "X") = "=IFERROR(VLOOKUP(Y" & i & ",Data!$B$15:$C$16,2,FALSE),"""")"
.Range("Y" & i).Value = "To Be Started"
.Range("T" & i).Value = "Checker"
.Range("S" & i).Value = "0"
End If
Next i
Range("A2").Select
End With
Application.ScreenUpdating = True
Reset_Form
Sheets("Task Entry Form").Select
Range("D3").Select
End Sub
'clear form
Sub Reset_Form()
Application.ScreenUpdating = False
Sheets("Task Entry Form").Select
Range("D3").ClearContents
Range("D5:D22").ClearContents
Range("E5:E22").ClearContents
Range("J5:J22").ClearContents
Range("K5:K22").ClearContents
End Sub
编辑:
这是文件中唯一的其他 VBA,在他们提交给跟踪器之前填写的选项卡上。
Option Explicit
'copies drawings from data tab based upon dropdown selection
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.CountLarge > 1 Then Exit Sub
If Target.Address(0, 0) <> "D3" Then Exit Sub
Application.ScreenUpdating = False
Dim fnd As Range, LastRow As Long
[D5:E22,I5:J22].ClearContents
If Target.Value <> "" Then
With Sheets("data")
LastRow = .Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
Set fnd = .Range("L:L").Find(Target, LookIn:=xlValues, lookat:=xlWhole)
If Not fnd Is Nothing Then
With .Range("M" & fnd.Row & ":M" & LastRow).SpecialCells(xlCellTypeConstants)
.Areas(1).Resize(, 2).Copy
Range("D5").PasteSpecial xlPasteValues
With Sheets("data").Range("O" & fnd.Row & ":O" & LastRow).SpecialCells(xlCellTypeConstants)
.Areas(1).Resize(, 2).Copy
End With
Range("I5").PasteSpecial xlPasteValues
End With
End If
End With
End If
Application.CutCopyMode = False
Application.ScreenUpdating = True
End Sub
解决方案
请使用下一个函数,能够检查分析范围的第二列中是否没有空的对应单元格:
Function compareCols(rng As Range) As String
Dim rngC1 As Range, cel As Range, i As Long
If rng.Rows.Count = 1 Then
If rng.Cells(1, 1) <> "" And rng.Cells(1, 2) = "" Then
compareCols = "No correspondent data in " & rng.Cells(1, 2).Address: Exit Function
Else
compareCols = "OK": Exit Function
End If
End If
Set rngC1 = rng.Columns(1).SpecialCells(xlCellTypeConstants)
For Each cel In rngC1.Cells
If cel.Value <> "" And cel.Offset(0, 1) = "" Then
compareCols = "No correspondent data in " & cel.Offset(0, 1).Address: Exit Function
End If
Next cel
compareCols = "OK"
End Function
在复制之前调用它会完成检查工作,正如(我理解)你需要的那样。
您应该在上面插入此代码行If Model.Rows.Count > 1...
:
'your existing code
Dim strOK As String
strOK = compareCols(Model)
If strOK <> "OK" Then MsgBox strOK: Exit Sub
strOK = "": strOK = compareCols(Drawing)
If strOK <> "OK" Then MsgBox strOK: Exit Sub
If Model.Rows.Count > 1 Then
'your existing code...
'...
'your existing code
编辑:
请测试您改编的代码,因为它应该......当然没有测试:
Sub CAD_Task_Entry()
Dim InstalDesc As String, Model As Range, Drawing As Range, Index As Long, m As Long, n As Long
Application.ScreenUpdating = False
'Copy data from the input screen to the task list.
Sheets("Task Entry Form").Select
InstalDesc = Range("D3")
Set Model = Range("D5", cells(rows.count, "D").End(xlUp)).Resize(, 2)
Set Drawing = Range("I5", cells(rows.count, "I").End(xlUp)).Resize(, 2)
Index = Range("Q2")
With Sheets("Task List")
'get first row
n = .Range("D:X").Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).row
If n = 3 Then n = 4 Else n = n + 2
'color first row
.Range("A" & n & ":Z" & n).Interior.color = 15189684
.cells(n, "D") = InstalDesc & " Summary"
'new code part____________________________
Dim strOK As String
strOK = compareCols(Model)
If strOK <> "OK" Then MsgBox strOK: Exit Sub
strOK = "": strOK = compareCols(Drawing)
If strOK <> "OK" Then MsgBox strOK: Exit Sub
'end new code part________________________
If Model.rows.count > 1 Then
Model.Columns(1).SpecialCells(xlCellTypeConstants).Copy
.cells(n + 1, "E").PasteSpecial xlPasteValues
Model.Columns(2).SpecialCells(xlCellTypeConstants).Copy
.cells(n + 1, "Q").PasteSpecial xlPasteValues
Else
Model.Columns(1).Copy
.cells(n + 1, "E").PasteSpecial xlPasteValues
Model.Columns(2).Copy
.cells(n + 1, "Q").PasteSpecial xlPasteValues
End If
If Drawing.rows.count > 1 Then
Drawing.Columns(1).SpecialCells(xlCellTypeConstants).Copy
.cells(n + Model.rows.count + 1, "F").PasteSpecial xlPasteValues
Drawing.Columns(2).SpecialCells(xlCellTypeConstants).Copy
.cells(n + Model.rows.count + 1, "Q").PasteSpecial xlPasteValues
Else
Drawing.Columns(1).Copy
.cells(n + Model.rows.count + 1, "F").PasteSpecial xlPasteValues
Drawing.Columns(2).Copy
.cells(n + Model.rows.count + 1, "Q").PasteSpecial xlPasteValues
End If
'get last row after inserting data
m = .Range("D:X").Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).row
End With
Application.ScreenUpdating = True
Reset_Form
Sheets("Task Entry Form").Select
Range("D3").Select
End Sub
推荐阅读
- r - 加载“插入符号”库时出错
- angular - 使用 concatMap 对多个 observables 进行排序
- javascript - 为类实例创建唯一 ID
- r - 仅选择 R 中数据框的数值变量
- c# - 使用异步查询多个 MySQL 实例 - 分片环境
- node.js - Docker 撰写错误以将 postgres 数据库与 Node API 连接
- javascript - 如何使用 array_column 创建目录
- vb.net - 删除 Visual Basic Web API 控制器中的 API 路径
- java - 如何从另一个 Maven 模块启动 Spring Boot 应用程序?
- java - Spring Cloud Gateway:不路由请求,最终遇到413请求实体太大