【问题标题】:How can I calculate the sum of Legacy Form Fields without werid scrolling?如何在没有奇怪滚动的情况下计算旧表单字段的总和?
【发布时间】:2014-11-14 14:32:04
【问题描述】:

我有一个 Word 文档,其中包含一个包含商品价格、订单金额和商品总和的表格,其中金额和商品总和是旧表单字段:

您可以通过复选框(以及旧表单字段)选择其他项目作为选项:

代码

现在我创建了一个计算项目总和的函数

Sub order_amount_Click()
    Dim amount As Integer
    Dim valueFromCell As String
    Dim list
    Dim value As Double

    amount = ActiveDocument.FormFields("order_amount").Result
    If amount > 0 Then
        valueFromCell = ThisDocument.Tables(1).Cell(5, 3).Range.Text
        list = Split(valueFromCell, " ")
        value = list(0)
        subsum = value * amount
        ActiveDocument.FormFields("order_amount_sum").Result = subsum
    Else
        ActiveDocument.FormFields("order_amount_sum").Result = 0
    End If

    CalculateSum
End Sub

另一个计算附加项目的项目总和(如果激活复选框)乘以订单金额的函数:

Sub optional_item_Click()
    Dim checkbox As Integer
    Dim valueFromCell As String
    Dim list
    Dim value As Double
    Dim amount As Integer
    Dim subsum As Double

    checkbox = ActiveDocument.FormFields("optional_item1").Result
    amount = ActiveDocument.FormFields("order_amount").Result

    If checkbox = 1 And amount > 0 Then
        valueFromCell = ThisDocument.Tables(1).Cell(7, 3).Range.Text
        list = Split(valueFromCell, " ")
        value = list(0)
        subsum = value * amount
        ActiveDocument.FormFields("optional_item1_sum").Result = subsum
    Else
        ActiveDocument.FormFields("optional_item1_sum").Result = 0
    End If

    CalculateSum
End Sub

(Click() 函数与 optional_item 字段一样多,总共 17 个 - 我还没有概括该函数。)

Subs 中的最后一行是一个函数调用,它计算净总和、增值税和最终总和

Function CalculateSum()
    Dim net As Double
    Dim vat As Double
    Dim total_sum As Double

    net = CDbl(ActiveDocument.FormFields("order_amount_sum").Result) + CDbl(ActiveDocument.FormFields("optional_item1_sum").Result) + CDbl(ActiveDocument.FormFields("optional_item2_sum").Result) + CDbl(ActiveDocument.FormFields("optional_item3_sum").Result) + CDbl(ActiveDocument.FormFields("optional_item4_sum").Result) + CDbl(ActiveDocument.FormFields("optional_item5_sum").Result) + CDbl(ActiveDocument.FormFields("optional_item6_sum").Result) + CDbl(ActiveDocument.FormFields("optional_item7_sum").Result) + CDbl(ActiveDocument.FormFields("optional_item8_sum").Result) + CDbl(ActiveDocument.FormFields("optional_item9_sum").Result)

    ' Cannot compile when line too long, so splitting into two statements
    net = net + CDbl(ActiveDocument.FormFields("optional_item10_sum").Result) + CDbl(ActiveDocument.FormFields("optional_item11_sum").Result) + CDbl(ActiveDocument.FormFields("optional_item12_sum").Result) + CDbl(ActiveDocument.FormFields("optional_item13_sum").Result) + CDbl(ActiveDocument.FormFields("optional_item14_sum").Result) + CDbl(ActiveDocument.FormFields("optional_item15_sum").Result) + CDbl(ActiveDocument.FormFields("optional_item16_sum").Result) + CDbl(ActiveDocument.FormFields("optional_item17_sum").Result)
    'MsgBox "net " & net
    ActiveDocument.FormFields("net_sum").Result = net

    vat = net * 0.19
    'MsgBox "vat " & vat
    ActiveDocument.FormFields("vat_sum").Result = vat

    total_sum = net + vat
    'MsgBox "total " & total_sum
    ActiveDocument.FormFields("total_sum").Result = total_sum
End Function

问题

代码本身运行良好,所有元素都计算正确。但是有两个主要问题使整个文档几乎无法使用(用户的所有操作都被限制在文档顶部输入他们的姓名,选择金额并取消/激活复选框;总和字段无法访问):

  1. 当我执行一项操作(例如输入金额)时,CalculateSum() 函数会明显地循环遍历所有 sum 字段(跨越三页)并沿着sum 字段奇怪地在文档上滚动。
  2. 当我单击第 2 或第 3 页上的复选框时,文档会向上滚动到第一页,在此我可以输入要订购的件数。

现在我怎样才能抑制所有在 sum 字段上的循环和奇怪的滚动?以及如何防止文档向上滚动到第一页?

任何帮助表示赞赏! (由于我是 VBA 新手,我也很感谢我的代码中的侧 cmets。)

更新 #1

我添加了screencast showing the error。

更新 #2

基本问题似乎是宏正在滚动到我在脚本中引用的位置,例如如果我正在使用

ActiveDocument.FormFields("total_sum").Result = total_sum

它正在滚动到 total_sum 字段。

【问题讨论】:

  • 你试过application.screenupdating = false和DoEvents吗?
  • 我还没有听说过这些,但会看看。感谢您的建议!
  • @vba4all application.screenupdating = false 已经阻止文档循环遍历每个 sum 字段 - 但仍向下滚动。我应该把DoEvents放在哪里?
  • 并没有真正的帮助,现在 - 当更改数量时 - 它奇怪地滚动并在第 2 页和第 3 页之间停止。如果我正在更改复选框,它会滚动并 - 至少 - 回到复选框位置。
  • 您必须提供说明如何重现此问题...

标签: vba ms-word scroll


【解决方案1】:

评论太难了...

对于 (b),您必须使用 VBA - 您不能使用我在其他地方建议的与 FormFields 复选框一起使用的技巧,只能使用 Content Control 复选框。

对于(c),类似这样(未测试)

确保为 optional_item1 设置了退出宏,并且还设置了退出时计算。我认为您也不需要 On Entry 宏。

Sub optional_item1_Click() 
  Call cb_Click("optional_item1") 
End Sub 

Sub cb_Click(ffname As String)
  ActiveDocument.Variables(ffname) = abs(int(ActiveDocument.FormFields(ffname).Checkbox.Value))
End Sub

在您的 Summa 列中,在复选框旁边,类似于

{ ={ DOCVARAIABLE optional_item1 }*X2 }

其中 X2 是包含 3,00 欧元值的单元格,所有 { } 是您可以在 Windows Word 上使用 ctrl-F9 插入的特殊字段代码大括号对。

但是

Word 是否正确解释您的欧元值取决于使用您的表单的用户的区域设置,(小数分隔符、组(千)分隔符、货币符号和货币符号的位置都可能会改变 Word 的行为。即使在欧元区我认为其中一些可能会有所不同。因此,如果用户不需要修改单元格中的乘数 3,00 Euros,最好将值直接插入 { = } 字段:

{ ={ DOCVARAIABLE optional_item1 }*3 }

您还可以使用 \# 数字格式在正数或 0 时为您提供所需的格式。但同样,Word 的数字格式设置工具不是独立于区域设置的)。

这些语言环境依赖性有时也是在 VBA 中而不是在域代码中做更多事情的原因。

【讨论】:

  • 我明天会更深入地研究它。现在感谢您的详细回答!
  • 这实际上并不能解决我奇怪的滚动问题。但我 +1 是因为它是一个经过充分研究且通常有用的答案。谢谢!
【解决方案2】:

作为AdamsTips found out elsewhere,替换这个

ActiveDocument.FormFields("myField").Result

通过这个

ActiveDocument.Bookmarks("myField").Range.Fields(1).Result

允许在不聚焦的情况下访问该字段。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-11
    • 2021-12-03
    • 1970-01-01
    • 2016-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多