【问题标题】:Updating data in Excel workbook with data in an other workbook使用其他工作簿中的数据更新 Excel 工作簿中的数据
【发布时间】:2015-09-30 10:34:40
【问题描述】:

我有一个名为“价目表”的工作簿,它包含多个工作表,每个工作表格式相同,但包含不同的产品分类。工作表格式如下:

 A          B          C      D

1 中国描述单价

2 A001 产品1 每个 20.00

3 D001 产品2 L 5.00

4 H001 Product3 Rol 4.00

每个月我们都会收到一份更新的价目表作为 Exel 工作簿。

过去我们获得了上述所有信息,但供应商发生了一些变化,我们只收到“产品代码”“条形码”和“价格”

我需要通过将“更新”中的产品代码与我的价目表中的产品代码相匹配来更新我的“价格表”。然后比较价格,如果价格不同,则应将“价格表”中的价格更改为“更新”

如果可能,它应该删除“更新”中的行,以便我们知道是否有新产品,如果有的话,删除“价格表”中的行对于停产产品,在“更新”中找不到产品代码。

“更新”包含大约 12000 行

有简单的方法吗?

已编辑以包含来自 OP 的评论和代码

我写了一些代码,但我不知道 VBA。

Sub UpdateMisilanious_Original()
' UpdateMisilanious Macro
' This will update the misilanious List
'The variable for the active line in Misilanious
Dim ALMis As Integer
    ALMis = 4
'The variable for the active line in Update
Dim ALUp As Integer
    ALUp = 2
'The varible for product code of Misilanious
Dim PrCMis As String
'The varible for product code of Update
Dim PrCUp As String
'The temp Varible for the Price
Dim NewPrice As Currency

    'Read the first Product code in Pricelist
    PrCMis = Worksheets("Misilanious").Range("A" & ALMis).Value
    'Start the Loop to update all Products
    Do While PrCMis <> ""
        PrCMis = Worksheets("Misilanious").Range("A" & ALMis).Value
        PrCUp = Worksheets("Update").Range("A" & ALUp).Value
        If PrCMis = PrCUp Then
            'Copy price from Update to Pricelist
            NewPrice = Worksheets("Update").Range("c" & ALUp).Value
            Worksheets("Misilanious").Range("E" & ALMis) = NewPrice
            'Add one to Active line of price list
            ALMis = ALMis + 1
            'Reset Active line of Update
            ALUp = 2
        Else:

            'Loop through update untilmaching Product code is found
            Do Until PrCMis = PrCUp
                ALUp = ALUp + 1
                PrCUp = Worksheets("Update").Range("A" & ALUp).Value
            Loop
            NewPrice = Worksheets("Update").Range("c" & ALUp).Value
            Worksheets("Misilanious").Range("E" & ALMis) = NewPrice
            'Add one to Active line of price list
            ALMis = ALMis + 1
            'Reset Active line of Update
            ALUp = 2
        End If
    Loop
    MsgBox "Update Done"

End Sub

【问题讨论】:

  • 我有以下想法应该如何工作:
  • 我有以下想法它应该如何工作:读取价目表中 A2 的值保存到变量 1。开始循环 读取 Update 中 A2 的值并与 variable1 比较 if = then 读取 Update 中 C2 的值并存储在 variable2 中,并将 variable2 写入 Price-list 的 D2。然后删除更新中的第 2 行。 If A2 in Update not = to Varible1 then go to next line read A3 and compare with Varible1 extr.. 如果读取值为 False 表示没有数据,结束循环并开始新循环与价格表中的下一行
  • 您对它应该如何工作的描述以及您想要删除行的事实意味着使用 VBA,但是您的问题被标记为 excel-formula。您要使用 VBA 解决方案吗?如果是这样,请告诉我们您做了什么以及您面临什么问题。另一方面,在处理行时删除它们将不允许在出现问题的情况下审核过程,但它再次与您想要使用的标准和质量水平有关。这可以通过公式来完成,但是您必须手动删除行(如果坚持这样做),或者使用 VBA。
  • 我写了一些代码但我不知道 VBA 。现在不知道怎么往前走,我想把代码复制到这里但是太长了
  • Sub UpdateMisilanious() ' UpdateMisilanious Macro ' 这将更新 misilanious List 'Misilanious Dim ALMis As Integer ALMis = 4 中活动行的变量 Update Dim ALUp As Integer ALUp = 2 'Misilanious Dim PrCMis As String 产品代码的变量 'Update Dim PrCUp As String 产品代码的变量 'Price Dim NewPrice As Currency 的临时变量

标签: excel vba


【解决方案1】:

编写代码的尝试很好,只是一个简短的评论:

如果产品停产,这部分将无限循环……

'Loop through update untilmaching Product code is found
Do Until PrCMis = PrCUp
    ALUp = ALUp + 1
    PrCUp = Worksheets("Update").Range("A" & ALUp).Value
Loop

下面提供的解决方案是遍历Price List中的产品,但不是再次遍历Update,而是找到匹配的记录。比较 Price ListUpdate,确定新价格和停产产品,然后从 UpdatePrice List 进行第二次比较 以添加新产品。看看下面的过程和建议的阅读材料,希望这将鼓励您继续致力于自动化所有这些繁琐和重复的日常任务。

此解决方案使用以下三个工作表:

  1. 更新:包含所有产品的最新价格更新。它可能包括新产品,“停产”产品也不包含在此列表中。它的数据是从E7 开始的连续单元格范围,由空白单元格分隔
  2. 价格列表:包含所有产品的列表以及相应的价格和其他相关数据。它的数据是从C6 开始的连续单元格范围,由空白单元格分隔
  3. 停产:包含停产产品的列表。它的数据是从B2 开始的连续单元格范围,由空白单元格分隔。如果该工作表不存在,该工作表将由该过程创建。

此代码运行价格列表和更新工作表之间的产品比较(双向)并更新新价格,添加新产品 并删除 价格表 数据中的停产产品,跟踪更新并将停产产品列表保存在单独的工作表中。

由于此代码使用了用户可能不知道的资源,因此我添加了一些说明它们的用途和建议的页面以供扩展阅读和理解,但如果您对代码有任何疑问,请告诉我。

Application Object (Excel), For...Next Statement, MsgBox Function,

Range Object (Excel), Variables & Constants, With Statement,

Worksheets Object (Excel), WorksheetFunction Object (Excel)

Option Explicit

Sub Update_Miscellaneous()

Rem Constants to Hold Starting Cell of Data Ranges (update as required)
'see [Variables & Constants]
Const kIniPlst As String = "C6"
Const kIniUpdt As String = "E7"
Const kIniDisc As String = "B2"

Rem Declare Objects as Variables
'see [Range Object (Excel)]
Dim rUpdt As Range, rMisc As Range, rDisc As Range

Rem Declare Process Variables
Dim sProd As String, dPric As Double, dPOld As Double

Dim Wsh As Worksheet, Rng As Range
Dim bProdUpdt As Byte, bPricUpdt As Byte
Dim bProd As Byte, bPric As Byte, bPOld As Byte, bPStt As Byte
Dim lRow0 As Long, lRow1 As Long, lNew As Long
Dim tTme As Date, sNow As String

    Rem Application Settings To Improve Performance
    'see [Application Object (Excel)]
    Application.ScreenUpdating = False
    Application.DisplayAlerts = False
    Application.EnableEvents = False

    Rem Set Time & Date
    tTme = Now
    sNow = Format(Now, " dd-mmm-yy hh:mm")

    Rem Set Objects
    'see [With Statement]
    With ThisWorkbook
        Set rUpdt = .Worksheets("Update").Range(kIniUpdt).CurrentRegion
        Set rMisc = .Worksheets("Price List").Range(kIniPlst).CurrentRegion
        On Error GoTo WshAdd
        Set rDisc = .Worksheets("Discontinued").Range(kIniDisc).CurrentRegion
        On Error GoTo 0
        Set rDisc = rDisc.Rows(1).Offset(rDisc.Rows.Count)
    End With

    Rem Set Field Position - Updated
    'see [WorksheetFunction Object (Excel)]
    With rUpdt
        Rem Set Field Position
        'Using Excel Worksheet Functions in VBA
        bProdUpdt = WorksheetFunction.Match("Product Code", .Rows(1), 0)
        'Can also be used with Application
        bPricUpdt = Application.Match("Price", .Rows(1), 0)
        Rem Set Body Range
        Set rUpdt = .Offset(1, 0).Resize(-1 + .Rows.Count)
    End With

    Rem Set Field Position - Miscellaneous
    With rMisc
        Rem Set AutoFilter Off
        If Not .Worksheet.AutoFilter Is Nothing Then .AutoFilter
        Rem Set Field Position
        bProd = WorksheetFunction.Match("PRC", .Rows(1), 0)
        bPric = WorksheetFunction.Match("PRICE", .Rows(1), 0)
        bPOld = WorksheetFunction.Match("Price.Old", .Rows(1), 0)
        bPStt = WorksheetFunction.Match("Status", .Rows(1), 0)
        Rem Set Body Range
        Set rMisc = .Offset(1, 0).Resize(-1 + .Rows.Count)
    End With

    Rem Update Current Products
    With rMisc

        Rem Set Latest Price
        'see [For...Next Statement]
        For lRow0 = 1 To .Rows.Count
            sProd = .Cells(lRow0, bProd).Value2
            dPOld = .Cells(lRow0, bPric).Value2

            Rem Get Latest Price
            lRow1 = 0
            On Error Resume Next
            lRow1 = WorksheetFunction.Match(sProd, rUpdt.Columns(bProdUpdt), 0)
            On Error GoTo 0
            If lRow1 <> 0 Then
                Rem Prices Comparison
                dPric = rUpdt.Cells(lRow1, bPricUpdt).Value2
                If dPric <> dPOld Then
                    Rem New Price
                    .Cells(lRow0, bPOld).Value = dPOld
                    .Cells(lRow0, bPric).Value = dPric
                    .Cells(lRow0, bPStt).Value = "Price Change" & sNow
                End If

            Else
                Rem Product Discontinued
                .Cells(lRow0, bPOld).Value = dPOld
                .Cells(lRow0, bPric).ClearContents
                .Cells(lRow0, bPStt).Value = "Discontinued" & sNow

    End If: Next: End With

    Rem Set New Products
    lNew = rMisc.Rows.Count
    With rUpdt
        For lRow0 = 1 To .Rows.Count
            sProd = .Cells(lRow0, bProd).Value2
            dPric = .Cells(lRow0, bPricUpdt).Value2

            Rem Get New Product
            lRow1 = 0
            On Error Resume Next
            lRow1 = WorksheetFunction.Match(sProd, rMisc.Columns(bProdUpdt), 0)
            On Error GoTo 0
            If lRow1 = 0 Then
                Rem Add New Product
                lNew = 1 + lNew
                With rMisc
                    .Cells(lNew, bProd).Value = sProd
                    .Cells(lNew, bPric).Value = dPric
                    .Cells(lNew, bPStt).Value = "!New Product" & sNow

    End With: End If: Next: End With

    Rem Reset Range Misc
    If lNew <> rMisc.Rows.Count Then
        Set rMisc = rMisc.CurrentRegion
        Set rMisc = rMisc.Offset(1, 0).Resize(-1 + rMisc.Rows.Count)
        Debug.Print xlPasteFormats, Now,
        rMisc.Rows(1).Copy
        rMisc.PasteSpecial Paste:=xlPasteFormats
        Application.CutCopyMode = False
        Debug.Print Now
    End If

    Rem Move Discontinued Records
    With rMisc

        Rem Sort By Status
        'Sort is a Property of the Worksheet Object
        With .Worksheet.Sort
            .SortFields.Clear
            .SortFields.Add Key:=rMisc.Columns(bPStt), _
                SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
            .SetRange rMisc
            .Header = xlYes
            .MatchCase = False
            .Orientation = xlTopToBottom
            .SortMethod = xlPinYin
            .Apply
        End With

        Rem Set AutoFilter
        .CurrentRegion.AutoFilter

        Rem Filter by Status\Discontinued
        .AutoFilter Field:=bPStt, Criteria1:="=*Discontinued*"
        On Error Resume Next
        Set Rng = .SpecialCells(xlCellTypeVisible)
        On Error GoTo 0

        Rem Set AutoFilter Off
        If Not .Worksheet.AutoFilter Is Nothing Then .AutoFilter

        Rem Work with Discontinued Records
        If Not Rng Is Nothing Then

            Rem Add Discontinued Records
            rDisc.Resize(Rng.Rows.Count).Value = Rng.Value2
            rDisc.CurrentRegion.Columns.AutoFit
            Application.Goto rDisc.Worksheet.Cells(1), 1
            Application.Goto rDisc.Cells(1)

            Rem Delete Discontinued Records
            'Rng.EntireRow.Delete       'Use this line if no other data in worksheet
            Rng.Delete Shift:=xlUp     'Use this line if there is other data in worksheet

    End If: End With

    Rem Sort Remaining Records By Product
    With rMisc.Worksheet.Sort
        .SortFields.Clear
        .SortFields.Add Key:=rMisc.Columns(bProd), _
            SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
        .SetRange rMisc
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With

    Rem Restate Application Settings
    Application.Goto rMisc.Worksheet.Cells(1), 1
    Application.Goto rMisc.Cells(1)
    Application.EnableEvents = True
    Application.DisplayAlerts = True
    Application.ScreenUpdating = True

    'see [MsgBox Function]
    Rem Process Completed
    MsgBox "Update Completed in " & Format(Now - tTme, "hh : mm : ss.001"), _
        vbApplicationModal + vbInformation + vbOKOnly, _
        "Product Price Update"

Exit Sub
WshAdd:
    'see [Worksheets Object (Excel)]
    Rem Add Worksheet Discontinued
    With ThisWorkbook
        Set Wsh = .Sheets.Add(After:=.Sheets(.Sheets.Count))
    End With
    Wsh.Name = "Discontinued"
    Wsh.Range(kIniDisc).Resize(, rMisc.Columns.Count).Value = rMisc.Rows(1).Value2
    Resume

End Sub

图1更新前的价目表

图2更新数据

图。 3 更新后的价目表

图。 4 更新后停产

【讨论】:

  • 感谢 EEM,您的代码运行良好,我将以此为基础学习更多 VBA。
  • 很高兴知道它鼓励您,我们可以在此过程中为您提供帮助,继续发布您的问题...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-16
  • 1970-01-01
  • 1970-01-01
  • 2013-08-10
  • 2023-01-28
  • 1970-01-01
相关资源
最近更新 更多