【问题标题】:Excel replace value without losing formattingExcel 替换值而不丢失格式
【发布时间】:2009-12-11 14:09:42
【问题描述】:

我有一个使用 Office 自动化自动化 Microsoft Excel (2003) 的应用程序。它所做的其中一件事是替换值。 我遇到的问题是,在替换值时,所有丰富的格式都会丢失,如下所述: http://support.microsoft.com/kb/177194

为了澄清,我在一个如下所示的单元格中将 valueX 替换为 valueY:
valueX 很棒

这会导致:
价值Y很棒


我尝试在 替换之前获取单元格中的格式,因此我可以保存哪些字符是粗体并在值被替换后应用格式。但我找不到获取每个字符格式的方法。 (C#)

有没有办法解决这个问题,而不使用上面网站上给出的分辨率?在 C# 或 Excel 中的一些解决方法

【问题讨论】:

    标签: c# .net excel office-interop


    【解决方案1】:

    在您的问题中,您提到您无法弄清楚如何在 C# 中获取每个字符的格式,但您可能可以在 Excel 中使用解决方法。我不确定 Excel 中的哪些对象通过互操作暴露给 C#,但也许我向您展示可以在 VBA 中完成的操作会有所帮助。

    我将提供三个部分来回答:

    1. 如何使用 VBA 在 Excel 中查找字符格式。
    2. 重置已替换单元格内容格式的复杂性。
    3. 在 Excel 中使用 VBA 之前/之后的一种可能方式。

    如何使用 VBA 在 Excel 中查找字符格式

    给定字符的格式通过Range.Characters.Font 对象公开。让我们来看看。假设您在 Excel 工作表的 Sheet1 的单元格 A1 中有以下内容:

    测试sting

    您可以从示例中看到第 3 和第 4 个字符是粗体。我们如何找到这些字符的这些属性和其他字体属性?这是一个 VBA 函数,它演示了您可以通过 Range.CharactersRange.Characters.Font 公开的一些属性:

    Sub IterateCharacters()
    Dim rng As Range
    Dim lngLen As Long
    Dim lngCount As Long
    Dim chr As Characters
    Set rng = ThisWorkbook.Worksheets("Sheet1").Range("A1")
    lngCount = 1
    lngLen = Len(rng.Value)
    
    Debug.Print "Count", "Text", "Font", "Color", "Size", "Bold"    
    
    Do While lngCount <= lngLen
        Set chr = rng.Characters(lngCount, 1)
        Debug.Print lngCount, chr.Text, chr.Font.Name, chr.Font.Color, chr.Font.Size, chr.Font.Bold
        lngCount = lngCount + 1
    Loop
    
    End Sub
    

    上面的代码会产生如下输出:

    计数文本字体颜色大小粗体 1 T 宋体 0 10 假 2 e 宋体 0 10 假 3 秒 Arial 0 10 真 4 t 宋体 0 10 真 5 i 宋体 0 10 假 6 n 宋体 0 10 假

    重置被替换单元格内容格式的复杂性

    我想这个问题的棘手部分实际上并不在于找到每个单独字符的格式(当然,假设在您的情况下它甚至是可能的)。困难的部分是“记住”每个字符的格式并在替换文本后重新应用格式。

    在最简单的情况下,替换字符串的长度始终与目标字符串的长度相同。如果valueX 将被简单地替换为valueY,并且它始终是相同的长度,那么保留格式非常容易。只需在运行 replace 方法之前获取格式,然后使用与之前完全相同的设置为每个字符重新应用格式。

    如果要替换单元格中的一个可能值,则稍微困难一些。在这种情况下,您需要通过替换字符串和目标字符串之间的长度差异来抵消替换格式,并且仅在替换字符串之后 这样做。

    在最丑陋的情况下,您有 n 个字符串将被替换,在这种情况下,当您解析回字符以应用格式时,您必须使用 n * difference 之类的东西进行后续替换。

    我确信有更好的算法来完成这项任务,但也许这最适合单独的 SO 问题。


    一种在 Excel 中使用 VBA 的可能方法

    理想情况下,您会找到一种直接从 C# 访问必要对象的方法,这样您就不必处理 VBA 代码和 Excel。但你可能没那么幸运。

    如果您必须在 Excel 中进行格式设置,可以采用以下一种方法。

    1. 将您的 Excel 工作表设置为 3 个工作表:Original,Copy,ReplacedValues
    2. 在运行 C# 代码之前,请确保 CopyOriginal 重复。
    3. 运行 C# 代码替换单元格内容时,将替换字符串的值粘贴到 ReplacedValues 工作表中。我建议您的范围地址(例如B2)在 A 列中,原始值在 B 列中,替换值在 C 列中。
    4. 运行您的 C# 代码后,编写一个方法,该方法将遍历 ReplacedValues 中列出的所有范围。
    5. 对于每个范围,您都可以引用 Copy 中的原始值(也许我的命名方案有点混乱)和 Original 中的更新值。
    6. 查找Copy 中的原始格式。使用字符串长度的差异来抵消并将您的格式应用回原始格式(这是您可以编写一些花哨的代码解析器来完成所有这些工作的地方)。

    可能有比上述过程更好的方法,但我认为它会很好地工作。

    【讨论】:

    • 本,多么令人难以置信的答案,圣牛。 Xta,这种方法在使用 C# 时不会有问题,尽管其中一些属性名称可能以“get_”或“set_”为前缀,但我期望的并不多。
    • 谢谢!我记得我花了多长时间才知道如何在 Excel 范围内格式化字符。我以前没有使用过 C# .NET 互操作,但我可能会在某个时候尝试一下,因为该语言使用起来更加优雅。
    • 哇,非常感谢!我还没有真正对其进行编程,但我相信我现在可以通过这个详细的答案让它工作。
    • @Ben:关于您的回复“我以前没有使用过 C# .NET 互操作,但这是我可能想在某个时候尝试的东西,因为该语言使用起来更加优雅。”小心将 C# 与 Excel 一起使用,在 C# 3.5 中使用 Excel 时,它确实非常不优雅;或以下。然而,C# 4.0 指日可待,应该会有所帮助。如果你想走这条路,我强烈建议要么等待 C# 4.0 正式发布,要么使用目前非常非常稳定的 Visual Studio 2010 beta。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-05
    • 1970-01-01
    相关资源
    最近更新 更多