【问题标题】:Excel VBA automatically updating columns (Date)Excel VBA 自动更新列(日期)
【发布时间】:2015-02-22 07:08:22
【问题描述】:

我正在创建一个执行客户退货的用户表单。我希望有一个(状态)列会自动更新。它指的是产品的到货日期。它可以工作,但是,当我更改系统日期时,状态栏不会改变。我需要做什么才能使其定期更新?以下是曾经有效的代码。

P.S 输入值时代码可以正常工作。但不会自我更新

Option Explicit
Dim dDate As Date

Private Sub cbP_CodeCR_Change()
Dim row As Long

row = cbP_CodeCR.ListIndex + 2



End Sub

Private Sub Fill_My_Combo(cbo As ComboBox)
    Dim wsInventory As Worksheet
    Dim nLastRow As Long
    Dim i As Long

    Set wsInventory = Worksheets("Inventory")
    nLastRow = wsInventory.Cells(Rows.Count, 1).End(xlUp).row ' Finds last row in Column 1

    cbo.Clear
    For i = 2 To nLastRow 'start at row 2
        cbo.AddItem wsInventory.Cells(i, 1)
    Next i
End Sub

Private Sub cmdCancel_Click()
Unload CustomerReturn
End Sub

Private Sub cmdEnter_Click()
Dim cust_ID As Integer
Dim prod_Code As Integer
Dim arr_date As Date
Dim stat As String
Dim status As String
Dim rowPosition As Integer

rowPosition = 1

Sheets("Customer Return").Select

Sheets("Customer Return").Cells(1, 1).Value = "Customer ID"
Sheets("Customer Return").Cells(1, 2).Value = "Product Code"
Sheets("Customer Return").Cells(1, 3).Value = "Arrival Date"
Sheets("Customer Return").Cells(1, 4).Value = "Status"


Do While (Len(Worksheets("Customer Return").Cells(rowPosition, 1).Value) <> 0)
rowPosition = rowPosition + 1
Loop
cust_ID = txtC_IDCR.Text
Sheets("Customer Return").Cells(rowPosition, 1).Value = cust_ID
prod_Code = cbP_CodeCR.Text
Sheets("Customer Return").Cells(rowPosition, 2).Value = prod_Code
arr_date = txtA_DateCR.Text
Sheets("Customer Return").Cells(rowPosition, 3).Value = arr_date
If ((arr_date - Date) <= 0) Then
Sheets("Customer Return").Cells(rowPosition, 4).Value = "Arrived"
Else
Sheets("Customer Return").Cells(rowPosition, 4).Value = "Waiting for Delivery"
End If

End Sub

Sub Recalc()

Range("C:C").Value = Format("dd/mm/yyyy")
Range("D:D").Calculate

Call StartTime

End Sub

Sub StartTime()

SchedRecalc = Now + TimeValue("00:00:10")
Application.OnTime SchedRecalc, "Recalc"

End Sub

Sub EndTime()

On Error Resume Next
Application.OnTime EarliestTime:=SchedRecalc, _
        Procedure:="Recalc", Schedule:=False

End Sub


Private Sub txtA_DateCR_AfterUpdate()

    With txtA_DateCR
    If .Text = "" Then
    .ForeColor = &HC0C0C0
    .Text = "dd/mm/yyyy"
    End If
    End With

End Sub

Private Sub txtA_DateCR_BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean)
    Exit Sub
    If Mid(txtA_DateCR.Value, 4, 2) > 12 Then
        MsgBox "Invalid date, make sure format is (dd/mm/yyyy)", vbCritical
        txtA_DateCR.Value = vbNullString
        txtA_DateCR.SetFocus
        Exit Sub
    End If

    dDate = DateSerial(Year(Date), Month(Date), Day(Date))
    txtA_DateCR.Value = Format(txtA_DateCR.Value, "dd/mm/yyyy")
    dDate = txtA_DateCR.Value
End Sub

Private Sub txtA_DateCR_Enter()

    With txtA_DateCR
    If .Text = "dd/mm/yyyy" Then
    .ForeColor = &H80000008
    .Text = ""
    End If
    End With

End Sub

Private Sub UserForm_Initialize()

txtA_DateCR.ForeColor = &HC0C0C0
txtA_DateCR.Text = "dd/mm/yyyy"
cmdEnter.SetFocus

Fill_My_Combo Me.cbP_CodeCR

End Sub

如果可能的话,非常感谢任何帮助。

【问题讨论】:

  • 定期运行 cmdEnter_Click(如在 Excel: Recalculating every x seconds 中)可能会在时间向前流动的最常见情况下起到作用
  • 我一直在寻找来自@xmojmr 但我感谢您的帮助。 (Y)
  • @xmojmr 我不太确定应该在哪里放置代码。就我而言,我也必须更改范围对吗?
  • @Edward 我会使用 StartTime, EndTime 逻辑,如链接肖恩的答案中所述。在Recalc 的实现中,将循环更新Customer Return 工作表中的所有填充行,方法是根据先前存储在3 列中的日期值和当前@987654334 计算列4 的新值@您可以将FormulaR1C1 存储到4 列中,沿着=IF(DAYS($C1;NOW())&lt;=0;"Arrived";"Waiting for Delivery") 存储一些东西,然后让Excel 的Calculate 为您施展魔法

标签: vba excel auto-update


【解决方案1】:

这应该在时间向前流动时最常见的情况下工作:

  1. 使用此代码创建一个实用模块AnyNameIsGood(它来自Sean Cheshire's answer to similar question,并调整了Recalc 主体)

    Dim ScheduledRecalc As Date
    
    Sub Recalc()
        Sheets("Customer Return").Range("D:D").Calculate
        Call StartTime
    End Sub
    
    Sub StartTime()
        ScheduledRecalc = Now + TimeValue("00:00:10")
        Application.OnTime ScheduledRecalc, "Recalc"
    End Sub
    
    Sub EndTime()
        On Error Resume Next
        Application.OnTime EarliestTime:=ScheduledRecalc, Procedure:="Recalc", Schedule:=False
    End Sub
    
  2. 将此代码添加到ThisWorkbook 模块以防止在关闭模块时出现不必要的行为:

    Private Sub Workbook_BeforeClose(Cancel As Boolean)
        Call EndTime
    End Sub
    
  3. CustomerReturn 模块(表单)中将您当前的代码更改为

    Private Sub cmdEnter_Click()
        ' ...
        arr_date = txtA_DateCR.Text
        Sheets("Customer Return").Cells(rowPosition, 3).Value = arr_date
        Sheets("Customer Return").Cells(rowPosition, 3).NumberFormat = "dd\/mm\/yyyy"
        Sheets("Customer Return").Cells(rowPosition, 4).FormulaR1C1 = "=IF(DAYS(R[0]C[-1],TODAY())<=0,""Arrived"",""Waiting for Delivery"")"
    End Sub
    

    它将格式化日期单元格,并使生成的 Status 公式对 Excel 的 Calculate Now (F9) 事件敏感。

  4. 在某处(例如在Workbook_Open 事件处理程序中)调用StartTime 实用程序(一次)。它将触发Status 列的自动重新计算。

步骤124 是可选的,如果不需要自动刷新,则不需要,因为最终用户可以随时按F9 刷新状态

【讨论】:

  • 非常感谢@xmojmr!我仍然面临这段代码的问题。格式好像不对。 imgur.com/522HjzG 我仍然在 excel 表中看到 m 和 y。但是,如果我双击它,它将更改为实际日期本身。我非常感谢您为此付出的时间和精力
  • @HOA 我没有手动为NumberFormatFormulaR1C1 分配创建代码。我使用 Excel 记录的宏来向我展示正确的语法。只需开始宏录制,转到日期单元格并将其设置为所需的自定义格式(或从预设日期格式列表中选择),停止宏并查看生成的代码。不同本地化的 Excel 版本(我的机器与您的机器)使用的格式可能有所不同
  • 明白了!修复。荣誉。希望在这个论坛上见到你
  • @HOA 你是怎么解决的?
  • 我录制了一个宏并突出显示该列并更改了所有格式
猜你喜欢
  • 2022-12-14
  • 2012-03-14
  • 1970-01-01
  • 1970-01-01
  • 2016-07-17
  • 1970-01-01
  • 2017-04-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多