【问题标题】:Excel range Format not rendered as expected (conversion issue)Excel 范围格式未按预期呈现(转换问题)
【发布时间】:2018-07-05 18:18:12
【问题描述】:

上下文:我有一个名为“ForUser”的工作表,第一行定义标题,下一行对应于数据。我有第二张名为“ForBuffer”的工作表,用于从数据库中检索数据。

“ForUser”中的每一列都与一种格式相关联,动态应用(格式可以由用户设置和更改)。在下面的示例中,“ForUser”表中有一个值为“Att $”的列标题,格式为美元。

    Dim objRs As ADODB.Recordset
    Dim rngDataBuffer As Range
    With Application.Workbooks(ThisWorkbook.Name()).Sheets("ForBuffer")
        Set rngDataBuffer = .Range("A1")
    End With
    rngDataBuffer.CopyFromRecordset Data:=objRs

数据从数据库中逐列加载,并使用 CopyFromRecordset 将数据参数设置为有效的 ADODB.Recordset 复制到名为“ForBuffer”的工作表中"

  Dim rDest As Range
  With Application.Workbooks(ThisWorkbook.Name()).Sheets("ForBuffer")
      With .Range("A1").CurrentRegion
       set rDest= .rows(1).Find( _
          What:="Att $", MatchCase:=True, LookIn:=xlFormulas, lookAt:=xlWhole)
      End With
  End With 

然后将此缓冲区复制到定义“Att $”标题的列中的“ForUser”工作表中。有些单元格设置了一些值,有些则没有。

  rngDataBuffer.Copy Destination:=rDest

我本可以使用类似

的方法将存储在 objRs 中的数据直接复制到 rDest 中(但这不是重点)
rDest.Offset(1).CopyFromRecordset Data:=objRs

Offset(1) 是保留“Att $”标题的第一行所必需的。

数据在数据库端保存为字符串,因此fall在rngDataBuffer

中有字符串

然后我使用类似的东西应用格式:

 rDest.Offset(1).Resize(rDest.rows.count-1).NumberFormat = "#,##0.00 [$USD]"

对于我使用的其他类型(美元货币、文本、百分比、浮点数、整数)

                    .NumberFormat = "#,##0.00 $"
                    .NumberFormat = "@"
                    .NumberFormat = "0.00%"
                    .NumberFormat = "0.0"
                    .NumberFormat = "0"

我可以检查格式是否已设置但未呈现,可能是因为数据已被复制为字符串。

如何将一系列单元格转换为某种“类型”(这里我说“类型”,因为“格式”似乎就是它的外观)。 ?

我尝试从某个单元格中复制值 1,然后使用不同的选项复制 PasteSpecial。我可以获得呈现的预期格式,但这有一个缺点,即在没有内容(null 或空)的单元格中设置 0(零)。在我的应用程序的上下文中,零单元格值或空单元格具有不同的含义。此外,此解决方案不适用于呈现日期。

我也尝试过根据类型转换数据。它总是以非常明确的消息失败:类型不匹配(错误 13)。值是一个字符串,但它们实际上可以转换为预期的类型。转换应用于范围值(多个单元格)

日期

 .Value = CDate(.Value)

对于数字“类型”(分别为整数、浮点数和货币)

.Value = CLgn(.Value)
.Value = CDbl(.Value)
.Value = CCur(.Value)

这些都不起作用。

我想出了一个让我非常惊讶的东西

.Value = .Value 

这到底是怎么回事,或者我应该问一下这背后的魔力是什么。顺便说一句,这适用于日期、货币和双精度,不适用于整数,也不适用于百分比!

【问题讨论】:

    标签: excel ado vba


    【解决方案1】:

    我不确定这是否会回答您的问题,但它可能会有所帮助,以下会将指定范围转换为货币(忽略空白单元格):

    Sheets("Sheet1").Range("B1:B13").Style = "Currency"
    'set the currency format for a specified range
    

    或者更具体地说,您可以执行以下操作:

    Dim rng As Range, c as Range
    Set rng = Range("A1:A50") 'set the range to be used
    
    For Each c In rng 'for each cell in the specified range
        If c.Value <> "" Then c.NumberFormat = "$#,##0.00"
        'if cell is not blank then format it
    Next c
    

    更新:

    Dim rng As Range, c as Range
    Set rng = Range("A1:A50") 'set the range to be used
    
    For Each c In rng 'for each cell in the specified range
        If c.Value <> "" Then c.NumberFormat = "$#,##0.00"
        'if cell is not blank then format it
        c.Value = c.Value
        'force the format into the cell
    Next c
    

    【讨论】:

    • 奇怪的是格式符合预期,但不是单元格的显示方式。设置格式后,如果我输入单元格并按回车键,则会出现良好的格式。我在做 .Value = 时取得了进展。价值 。它有效,但对于整数既不是百分比情况!我将查看范围对象的 Style 属性。
    • @pascalsautot 我已经测试了我的答案的更新版本,它会强制单元格以正确的格式显示,请尝试一下,如果有任何进一步的问题,请告诉我。
    • 这就是我想出的。仍然为大范围(1000 x 200 单元格)跳过单元格不是理想的解决方案。无论如何,我都想了解这一切背后的逻辑,以及为什么在设置格式时不应用它。 .value = .value 隐藏了什么。在我练习过的所有语言中,这种赋值不应该改变任何东西,除非值的设置(即使它没有改变)触发事件背后似乎是这种情况。这种把戏没有记录在案,或者我的眼睛确实越过了它。因此,您的帮助很友善,但没有回答我的问题。
    猜你喜欢
    • 1970-01-01
    • 2022-09-23
    • 2017-01-01
    • 1970-01-01
    • 2017-02-23
    • 2021-06-27
    • 2018-10-01
    • 2014-09-29
    相关资源
    最近更新 更多