修复 VB Excel 宏、搜索和 copy/paste 循环,2 张

Fix VB Excel Macro, search and copy/paste loop, 2 sheets

我是一名编码新手。我找到了一些示例和教程来将我的代码放到它所在的位置,但它 return 是

error "400"

我发现诊断起来并不那么容易。我的目标很简单。我有一个 2 sheet 工作簿。 Sheet1是订单("PO"),sheet2是数据库("DataBase")。我在工作簿中有这个子例程(不是 sheet 之一)。它提示用户扫描条形码,然后搜索 sheet "DataBase" 该部件号,然后 copy/pastes 右边的下 3 个单元格返回原始 sheet "PO"。

还有一些内置功能,例如扫描特定条形码时终止循环的功能 (xxxDONExxxx)。如果找不到匹配项,我也在尝试找到一种方法 return 一条错误消息 (ErrMsg2)。

如果我使用 F8 单步执行子例程,它会通过扫描仪输入,然后失败并显示注释 ('FAIL')。我将不胜感激,希望能帮助我完成这项工作。

Option Explicit

Sub inventory()

'**** Define variables ****'
Dim partnumber As String
Dim lastrow As Integer
Dim i As Integer
Dim x As Integer
'Dim xxxDONExxxx As String

'**** Clear paste area in sheet "PO" ****'
Sheets("PO").Range("A17:F31").ClearContents

'**** Set row count ****'
lastrow = 100 'Sheets("DataBase").Range("B500").End(x1Up).Row

'**** select first cell to paste in****'
Range("A17").Select

'**** loop for scanning up to 30 lines ****'
For i = 1 To 30

    '**** Prompt for input ****'
    partnumber = InputBox("SCAN PART NUMBER")

    '**** Abort if DONE code is scanned ****'
    If ("partnumber") = ("xxxDONExxxx") Then GoTo ErrMsg1

        '**** search DataBase for match in B, copy CDE /paste in PO BDE****'
        For x = 2 To lastrow

        If ("partnumber") = Sheets("DataBase").Range("x, 2") Then '*FAIL*'
        ActiveCell.Offset(0, 1) = Sheets("DataBase").Cells(x, 1)
        ActiveCell.Offset(0, 2) = Sheets("DataBase").Cells(x, 2)
        ActiveCell.Offset(0, 3) = Sheets("DataBase").Cells(x, 3)

        End If

        Next x

Next i

ErrMsg1:
MsgBox ("Operation Done - user input")
ErrMsg2:
MsgBox ("Part Number does not Exist, add to DataBase!")
End Sub

Sheet 1 - "PO"

Sheet 2 - "Database"

我是 application.match 的超级粉丝。例如:

If IsNumeric(Application.Match(LookUpValue, LookUpRange, 0)) Then
startCol = Application.Match(LookUpValue, LookUpRange, 0)
Else
MsgBox "Unable to find " & LookUpValue & " within " & LookUpRange & ". Please check the data and try again. The macro will now exit"
End
End If

这会测试该项目是否存在于数据集中,如果存在则对其进行处理。如果不存在,您可以抛出一条错误消息。根据您的需要稍微按摩一下:

If IsNumeric(Application.Match(PartNumber, DataBaseRange, 0)) Then
'Do things with matching
Else
'Do things when you don't have a match
End
End If

我知道有更有效的方法可以做到这一点,但这会达到您的预期:

Option Explicit

Sub inventory()
'**** Define variables ****'
Dim wsData As Worksheet: Set wsData = Sheets("DataBase")
Dim wsPO As Worksheet: Set wsPO = Sheets("PO")
Dim partnumber As String
Dim lastrow As Long
Dim i As Long
Dim x As Long
Dim Found As String
Found = False
'**** Clear paste area in sheet "PO" ****'
wsPO.Range("A17:F31").ClearContents

'**** Set row count on Database Sheet ****'
lastrow = wsData.Cells(wsData.Rows.Count, "B").End(xlUp).Row

'select the last row with data in the given range
wsPO.Range("A17").Select

ScanNext:
'**** Prompt for input ****'
partnumber = InputBox("SCAN PART NUMBER")

'**** Abort if DONE code is scanned ****'
If partnumber = "xxxDONExxxx" Then
    MsgBox ("Operation Done - user input")
    Exit Sub
Else
    Selection.Value = partnumber
End If

'**** search DataBase for match in B, copy CDE /paste in PO BDE****'
 For x = 2 To lastrow
     If wsPO.Cells(Selection.Row, 1) = wsData.Cells(x, 2) Then
         wsPO.Cells(Selection.Row, 2) = wsData.Cells(x, 3)
         wsPO.Cells(Selection.Row, 5) = wsData.Cells(x, 4)
         wsPO.Cells(Selection.Row, 6) = wsData.Cells(x, 5)
         Found = "True"
     End If
 Next x

 If Found = "False" Then
     MsgBox "Product Not Found in Database!", vbInformation
     Selection.Offset(-1, 0).Select
 Else
     Found = "False"
 End If


If Selection.Row < 31 Then
    Selection.Offset(1, 0).Select
    GoTo ScanNext
Else
    MsgBox "This inventory page is now full!", vbInformation
End If
End Sub

试试这个重新思考的版本。您应该创建一个 Sub 以将新的未知项目添加到数据库范围内,否则您需要退出当前进程,将新项目添加到数据库中,然后重新扫描所有项目从头开始!

Option Explicit

Sub inventory()

    '**** Define variables ****'
    Const STOP_ID As String = "xxxDONExxxx"
    Const START_ROW As Long = 17 ' based on "A17:F31"
    Const LAST_ROW As Long = 31 ' based on "A17:F31"

    Dim partnumber As String, sDescription As String, i As Long
    Dim oRngDataBase As Range

    '**** Clear paste area in sheet "PO" ****'
    Worksheets("PO").Range("A17:F31").ClearContents

    ' Determine the actual database range
    Set oRngDataBase = Intersect(Worksheets("DataBase").UsedRange, Worksheets("DataBase").Columns("B:E"))
    i = START_ROW
    On Error Resume Next
    Do
        partnumber = InputBox("SCAN PART NUMBER")
        If Len(partnumber) = 0 Then
            If partnumber = STOP_ID Then
                MsgBox "Operation Done - user input", vbInformation + vbOKOnly
                Exit Do
            End If
            sDescription = WorksheetFunction.VLookup(partnumber, oRngDataBase, 2, False) ' Description
            If Len(sDescription) = 0 Then
                If vbYes = MsgBox("Part Number (" & partnumber & ") does not Exist, add to DataBase Now?", vbExclamation + vbYesNo) Then
                    ' Suggest you to create a new Sub to insert data and call it here

                    ' Update the Database Range once added new item
                    Set oRngDataBase = Intersect(Worksheets("DataBase").UsedRange, Worksheets("DataBase").Columns("B:E"))
                End If
                'NOTE:  Answer No will skip this scanned unknown partnumber
            Else
                Worksheets("PO").Cells(i, "A").Value = partnumber
                Worksheets("PO").Cells(i, "B").Value = sDescription
                Worksheets("PO").Cells(i, "C").Value = WorksheetFunction.VLookup(partnumber, oRngDataBase, 3, False) ' QTY
                Worksheets("PO").Cells(i, "D").Value = WorksheetFunction.VLookup(partnumber, oRngDataBase, 4, False) ' PRICE
                i = i + 1
            End If
        End If
    Loop Until i > LAST_ROW
    On Error GoTo 0
    Set oRngDataBase = Nothing
End Sub