【问题标题】:Excel Macro, inserting internationally valid formula during run-timeExcel 宏,在运行时插入国际有效的公式
【发布时间】:2012-10-26 05:07:20
【问题描述】:

我有一个带有宏的 Excel 电子表格,它可以插入条件格式,如下所示:

Selection.FormatConditions.Add Type:=xlExpression, Formula1:="=UND($A3=""" & lastName & """; $B3=""" & firstName & """)"

如您所见,我使用了德语公式来表示“AND”(即“UND”),显然,当我在法语或英语版本的 Excel 上使用此代码时,它就不起作用了。 通常公式会自动本地化,但如何在运行时插入适用于所有版本的公式?

【问题讨论】:

标签: vba excel excel-formula internationalization


【解决方案1】:

我知道这个线程已经很久了,有人可能已经找到了一个优雅的解决方案,但我也遇到了同样的问题,我需要在不修改工作表、创建临时单元格内容或命名范围的情况下应用条件格式。所有用户使用的都是英文版的Excel,所以公式中用到的函数是一样的,只是地域设置不同,参数分隔符也不同;在挪威语中,它是“;”而不是“,”,我猜很像欧洲其他地区。

例如,我需要自动创建条件格式,使用 Excel 公式满足以下条件:

.FormatConditions.Add xlExpression, Formula1:="=AND(ISNUMBER(B" & I & "),B" & I & ">=" & Ul1 & ")"

其中“Ul1”是在上一步中定义的值,它对解决方案并不重要。

但是,我需要能够在具有挪威语和英语设置的计算机上运行它

我从 Andrew Pulsom 那里找到了一个非常简短的解决方案:https://www.mrexcel.com/board/threads/french-vba-vs-english-vba.729570/。他只是把参数分隔符变成了一个变量:

If Application.International(xlDecimalSeparator) = "," Then
    Sep = ";"
Else
    Sep = ","
End If

Cl1 = "=AND(ISNUMBER(B" & I & ")" & Sep & "B" & I & "<" & Ul1 & ")"

对我来说就像一个魅力:)

我知道这只能解决部分问题,但我认为这可能适用于许多使用具有本地区域设置的英语 Office 安装的国际公司。

【讨论】:

    【解决方案2】:

    更多解释请参考链接:https://bettersolutions.com/csharp/excel-interop/locale-culture.htm

    CultureInfo baseCulture = System.Threading.Thread.CurrentThread.CurrentCulture; 
    Thread.CurrentThread.CurrentCulture = new CultureInfo(xlapp.LanguageSettings.LanguageID(Office.MsoAppLanguageID.msoLanguageIDUI)); 
    // do something 
    System.Threading.Thread.CurrentThread.CurrentCulture = baseCulture; 
    

    【讨论】:

    • 请解释一下
    • C# != VBA.. 哎呀,VBA != .NET - 这个“答案”与问题完全无关。
    【解决方案3】:

    好的,谢谢你帮我解决这个问题,你帮我破解了这个。

    确实不能只用英文。对公式进行操作时可以使用英语,例如。通过设置编码Range("A1").formula="AND(TRUE)",但这不适用于FormatConditions

    我的解决方案是一个将公式临时写入单元格的函数,通过FormulaLocal 属性读取它,然后返回本地化公式,如下所示:

    Function GetLocalizedFormula(formula As String)
    ' returns the English formula from the parameter in the local format
      Dim temporary As String
      temporary = Range("A1").formula
      Range("A1").formula = formula
      Dim result As String
      result = Range("A1").FormulaLocal
      Range("A1").formula = temporary
      GetLocalizedFormula = result
    End Function
    

    返回的公式可用于FormatConditions,稍后在其他语言版本的 Excel 中打开文档时,该公式将重新本地化或取消本地化。

    【讨论】:

    • 顺便说一句。这会暂时破坏 A1 的值,然后再次将其写回。在我的实现中没有问题,但是如果您自己使用它,您可能需要更改临时单元格。
    • 您也可以为此创建一个临时工作表,因此您永远不会干扰您拥有的任何现有工作表功能(与 A1 相关)
    • 公式的自动翻译也不适用于验证功能,但这个解决方案节省了我的时间。
    • 此解决方法也仅限于子过程中使用,因为函数不允许更改任何单元格...
    • 只是一个 VBA 提示:不要给自己一种错误的印象,即直到 Dim 行才声明变量。在 VBA 中,变量是提升的,这意味着将 Dims 放在使用之前或函数的开头是相同的,但前者最终会欺骗你做错事。
    【解决方案4】:

    谢谢大家!我发现这篇文章很有用。

    我的解决方案是其他人的组合,我添加它以防有人发现它有用。

    Dim tempform As String
    Dim strlocalform1 As String
    Dim strlocalform2 As String
    
    ' Get formula stored in WorksheetA Cell O1 =IFERROR(a,b)
    tempform = Worksheets("Sheet").Range("O1").Formula
    
    ' Extract from the formula IFERROR statement in local language.
    strlocalform1 = Mid(tempform, 2, InStr(1, tempform, "(") - 1)
    
    ' Extract from the formula separator , (comma) in local settings.
    strlocalform2 = Mid(tempform, InStr(1, tempform, "a") + 1, 1)
    
    ' Add formula in local language to desired field.
    pvt.CalculatedFields.Add Name:="NewField", Formula:="=" & strlocalform1 & "FORMULA" & strlocalform2 & ")"
    

    希望这会有所帮助!

    【讨论】:

      【解决方案5】:

      我刚刚在德语 Excel 论坛中发现了一个非常优雅的solution to the problem。这不会写入虚拟单元格,而是使用临时命名范围。我使用最初的想法(归功于 bst)为两个方向编写了一个翻译函数。

      将本地化公式转换为英文公式:

      Public Function TranslateFormula_LocalToGeneric(ByVal iFormula As String) As String
          Names.Add "temporaryFormula", RefersToLocal:=iFormula
          TranslateFormula_LocalToGeneric = Names("temporaryFormula").RefersTo
          Names("temporaryFormula").Delete
      End Function
      


      将英文公式转换为本地化公式:

      Public Function TranslateFormula_GenericToLocal(ByVal iFormula As String) As String
          Names.Add "temporaryFormula", RefersTo:=iFormula
          TranslateFormula_GenericToLocal = Names("temporaryFormula").RefersToLocal
          Names("temporaryFormula").Delete
      End Function
      

      如果您需要处理条件格式中的公式,这将非常方便,因为这些公式始终存储为本地化公式(但您可能需要它们的通用版本,例如使用Application.Evaluate(genericFormula)) .

      【讨论】:

      • 这是一个好主意,但它会将工作表名称添加到范围引用中(“$B$9”变为“MySheet!$B$9”并且 FormatConditions 不喜欢具有工作表名称的范围.
      • 如果它有效,那就太好了。不幸的是,事实并非如此。 (在我的电脑上,RefersTo 也包含本地公式。)
      • @MarcusMangelsdorf - 对我来说,通过添加名称的公式翻译在两个方向都有效,没有任何问题 +1(当地语言德语 :-)
      • 在某些情况下效果很好,但在某些情况下取决于所选单元格...如果所选单元格位于第 18 行,“$B2”将变为“MySheet!$B19”, “MySheet!$B$12”如果它在第 11 行...
      • 它不起作用我收到一个错误,比如我不能在 RefersTo 字段中使用公式。
      【解决方案6】:

      将公式存储(简单版本)在工作簿的(隐藏)单元格中。

      然后,当您打开工作簿时,该公式将由 Excel 自动为用户翻译。

      现在你只需要在你的脚本中解析这个公式(找到左括号“(”并将过去的左边:

      使用类似的东西:

      strLocalizedFormula = Mid(strYourFormula, 2, InStr(1, strYourFormula, "(") - 2)

      其中strYourFormula 将是您工作表中公式的副本。

      我希望这可行,因为我只使用英语环境。

      同样来自阅读: http://vantedbits.blogspot.nl/2010/10/excel-vba-tip-translate-formulas.html 我认为您应该(仅)能够使用 VBA 中的英文版单元格公式。

      【讨论】:

        【解决方案7】:

        也许试试这个(未经测试,因为我只安装了英文版)

        使用 Range.Formula 将您的国际版公式写入一个偏僻的单元格。然后从Range.FormulaLocal读回来,并将该字符串写入FormatConditions

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-01-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多