Is there a way to programmatically convert VB6 Formatting strings to .NET Formatting strings?

半城伤御伤魂 提交于 2019-11-27 05:10:53

The formatting routine that VB6 uses is actually built into the operating system. Oleaut32.dll, the VarFormat() function. It's been around for 15 years and will be around for ever, considering how much code relies on it. Trying to translate the formatting strings to a .NET composite formatting string is a hopeless task. Just use the OS function.

Here's a sample program that does this, using the examples from the linked thread:

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);
}

Your best bet might be to write the conversion library yourself, but that probably wasn't the answer you had hoped to get.

Here's some F# code that translates the majority of pre-defined and custom VB6-style numeric and date format strings to something suitable for String.Format. It's easily called from C# or VB of course.

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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!