繁体   English   中英

Excel 和 VBA 给出不同的答案

[英]Excel and VBA Gives Different Answers

我在数据验证中遇到了一个奇怪的问题(可能是一个错误)

当我使用下面的代码进行数据验证时,Excel 正在创建一个下拉列表,但将字符串添加为一行。 但是当我从 Excel 数据验证菜单中写入相同的字符串时,Excel 将下拉列表与我想要的多个项目分开。 例如,假设字符串为“A;B;C”当我通过 VBA 执行此操作时,下拉菜单显示“A;B;C”为 1 行,但当我单击数据验证菜单并手动编写“A;B;C”时, Excel 正在使用“A”、“B”、“C”创建 3 行下拉列表,这是完全奇怪的行为。 您可能会看到如下代码。 我添加视频链接以更好地解释。 https://streamable.com/a75kud

Public arrAddress As String
Sub DynamicDataVal()

Dim rng As Range
Dim cll As Range
Dim dValicationCount As Long
Dim un As String
Dim DValidationList As Range
Dim DValidationListString As String
Dim seper As String
Dim col As New Collection, a
Dim colIt As Variant
Dim arr() As Variant

un = "Sayin " & Environ("UserName")

On Error Resume Next
Set rng = Application.InputBox("Lutfen Veri Alanini Seciniz", un, ActiveCell.Address, , , , , 8)
If rng Is Nothing Then Exit Sub

Set cll = ActiveCell
dValicationCount = cll.SpecialCells(xlCellTypeSameValidation).Count

If dValicationCount = 0 Then
    arr = rng.Offset(1, 0).Resize(rng.Resize(, 1).Cells.Count - 1, 1).Value
    arrAddress = rng.Address(External:=True)
    For Each a In arr
       col.Add a, a
    Next a
    seper = ListSeperatorMod.GetListSeparator
    For Each colIt In col
         DValidationListString = DValidationListString & seper & colIt
    Next colIt
    DValidationListString = Right(DValidationListString, Len(DValidationListString) - 1)
    On Error GoTo 0
    With cll.Validation
        .Delete
        .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, _
        Formula1:=DValidationListString
    End With
Else
    If rng.Validation.Type <> 3 Then
        Exit Sub
    Else
        'Will be done
    End If
End If
On Error GoTo 0
End Sub
Private Declare Function GetLocaleInfo Lib "kernel32" Alias "GetLocaleInfoA" _
    (ByVal Locale As Long, ByVal LCType As Long, ByVal lpLCData As String, ByVal cchData As Long) As Long

Private Declare Function GetUserDefaultLCID% Lib "kernel32" ()
Private Const LOCALE_SLIST = &HC

Public Function GetListSeparator() As String

    Dim ListSeparator As String
    Dim iRetVal1 As Long
    Dim iRetVal2 As Long
    Dim lpLCDataVar As String

    Dim Position As Integer
    Dim Locale As Long

    Locale = GetUserDefaultLCID()

    iRetVal1 = GetLocaleInfo(Locale, LOCALE_SLIST, lpLCDataVar, 0)

    ListSeparator = String$(iRetVal1, 0)

    iRetVal2 = GetLocaleInfo(Locale, LOCALE_SLIST, ListSeparator, iRetVal1)

    Position = InStr(ListSeparator, Chr$(0))
    If Position > 0 Then
        ListSeparator = Left$(ListSeparator, Position - 1)
    End If

    GetListSeparator = ListSeparator

End Function

这是设计使然,与使用 VBA 在单元格中输入公式时看到的行为相同:您始终在 VBA 中使用“US”列表分隔符,而不是(例如)特定于区域设置的分隔符,例如; .

这与通过用户界面输入公式不同,在用户界面中您始终使用特定于区域设置的分隔符。

所以在 VBA 你可以使用:

Range("A1").Formula = "=MAX(A1, B2)"

如果您的语言环境分隔符是; 然后公式在工作表上显示为:

=MAX(A1; B2)

这允许相同的 VBA 到 function 跨不同的语言环境而无需修改

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM