【问题标题】:Is there a way to programmatically convert VB6 Formatting strings to .NET Formatting strings?有没有办法以编程方式将 VB6 格式化字符串转换为 .NET 格式化字符串?
【发布时间】:2025-11-22 00:05:03
【问题描述】:
  1. 有人知道 VB6 格式字符串的好参考吗?
  2. 有人知道从 VB6 格式化字符串到 .NET 字符串的转换器吗?

我正在将大型 VB6 代码库移植到 .NET。它是一个以数据库为中心的软件,数据库本身包含 VB6 格式字符串,这些字符串稍后会被加载并用于显示数据库中的其他数据。

我的问题,比如this article,是如何移植这个。但是,为该问题选择的答案不足以满足我的需求。依赖专门为向后兼容而设计的库与我受雇专门移植的语言感到不舒服。

【问题讨论】:

  • 数据库中保存的格式是已知集合吗?如果是这样,您最好只编写脚本来对该子集进行简单的数据库更新,而不是找到一个工具。无论如何,您都需要仔细检查结果。
  • :-D 我希望。已经完全想到了——但它不是一个已知的集合(即使它们中的大多数为空的)。不幸的是,它也有不利的一面,即我们的成千上万的用户可能会陷入困境……有办法绕过它——但查找和替换并不能真正起作用,不。

标签: c# string-formatting vb6-migration


【解决方案1】:

VB6 使用的格式化程序实际上是内置在操作系统中的。 Oleaut32.dll,VarFormat() 函数。考虑到有多少代码依赖它,它已经存在了 15 年并且将永远存在。尝试将格式字符串转换为 .NET 复合格式字符串是一项无望的任务。只需使用操作系统功能即可。

这是一个执行此操作的示例程序,使用链接线程中的示例:

using System;
using System.Runtime.InteropServices;

class Program {
    static void Main(string[] args) {
        Console.WriteLine(Vb6Format("hi there", ">"));
        Console.WriteLine(Vb6Format("hI tHeRe", "<"));
        Console.WriteLine(Vb6Format("hi there", ">!@@@... not @@@@@"));
        Console.ReadLine();
    }

    public static string Vb6Format(object expr, string format) {
        string result;
        int hr = VarFormat(ref expr, format, 0, 0, 0, out result);
        if (hr != 0) throw new COMException("Format error", hr);
        return result;
    }
    [DllImport("oleaut32.dll", CharSet = CharSet.Unicode)]
    private static extern int VarFormat(ref object expr, string format, int firstDay, int firstWeek, int flags,
        [MarshalAs(UnmanagedType.BStr)] out string result);
}

【讨论】:

  • 汉斯,你是救世主。谢谢你的背景。我没有意识到历史;给人的印象是它是 VB6 的主要内容。
  • 简单而狡猾,我喜欢这样,+1
【解决方案2】:

您最好的选择可能是自己编写转换库,但这可能不是您希望得到的答案。

【讨论】:

  • 我真的没有抱太大希望...这就是为什么我还要求提供 VB6 格式字符串资源,因为我想我可能需要重新编写它。
【解决方案3】:

这里有一些 F# 代码,可将大多数预定义和自定义 VB6 样式的数字和日期格式字符串转换为适合 String.Format 的字符串。当然,它很容易从 C# 或 VB 中调用。

open System

module VB6Format =

    /// Converts a VB6-style format string to something suitable for String.Format()
    let Convert(vb6Format) =
        if String.IsNullOrWhiteSpace(vb6Format) then "{0}" else
        match if vb6Format.Length > 1 then vb6Format.ToUpperInvariant() else vb6Format with
        // PREDEFINED NUMERIC: http://msdn.microsoft.com/en-us/library/y006s0cz(v=vs.71).aspx
        | "GENERAL NUMBER" | "G"       -> "{0:G}"
        | "g"                          -> "{0:g}"
        | "CURRENCY" | "C" | "c"       -> "{0:C}"
        | "FIXED" | "F"                -> "{0:F}"
        | "f"                          -> "{0:f}"
        | "STANDARD" | "N" | "n"       -> "{0:N}"
        | "PERCENT" | "P" | "p"        -> "{0:P}"
        | "SCIENTIFIC"                 -> "{0:E2}"
        | "E" | "e"                    -> "{0:E6}"
        | "D" | "d"                    -> "{0:D}"
        | "X" | "x"                    -> "{0:X}"
        | "YES/NO" | "ON/OFF"          // we can't support these
        | "TRUE/FALSE"                 -> "{0}"
        // PREDEFINED DATE/TIME: http://msdn.microsoft.com/en-us/library/362btx8f(v=VS.71).aspx
        | "GENERAL DATE" | "G"         -> "{0:G}"
        | "LONG DATE" | "D"            -> "{0:D}"
        | "MEDIUM DATE"
        | "SHORT DATE" | "d"           -> "{0:d}"
        | "LONG TIME" | "T"            -> "{0:T}"
        | "MEDIUM TIME"
        | "SHORT TIME" | "t"           -> "{0:t}"
        | "M" | "m"                    -> "{0:M}"
        | "R" | "r"                    -> "{0:R}"
        | "s"                          -> "{0:s}"
        | "u"                          -> "{0:u}"
        | "U"                          -> "{0:U}"
        | "Y" | "y"                    -> "{0:Y}"
        // USER-DEFINED: http://msdn.microsoft.com/en-us/library/4fb56f4y(v=vs.71).aspx
        //               http://msdn.microsoft.com/en-us/library/73ctwf33(v=VS.71).aspx
        // The user-defined format strings translate more-or-less exactly, so we're just going to use them.
        | _                            -> sprintf "{0:%s}" vb6Format

【讨论】:

  • 我看不出这段代码是如何工作的。在VB6格式字符串dd-mm-yy hh:mm:ss中,第一个mm是月,第二个mm是分钟。对于.Net,它们都是几分钟。它也不考虑转义文字和引用文字。