8
  1. Does anyone know of a good reference for VB6 format-strings?
  2. Does anyone know of a converter from VB6 formatting strings to .NET strings?

I'm working on porting a large VB6 code base to .NET. It is a database centric piece of software, and the database itself holds VB6 format-strings which are later loaded and used to display other data in the database.

My question, like this article, is how to port this. However the answer chosen for that question isn't adequate for my needs. I'm uncomfortable relying on libraries specifically designed for backwards compatibility with a language I've been specifically hired to port away.

Community
  • 1
  • 1
Chris Pfohl
  • 18,220
  • 9
  • 68
  • 111
  • Are the formats held in the database a known set? If so, you may be better off just writing scripts to do simple database updates on that subset than finding a tool. You'll need to double-check the results anyway. – Wonko the Sane Nov 01 '10 at 19:51
  • :-D I wish. Totally thought of that already-but it's not a known set (even if most of them *are* null). Unfortunately it also has the downside of meaning that our thousands of users could get stuck in limbo...there's ways around it-but a find and replace wouldn't really work, no. – Chris Pfohl Nov 01 '10 at 19:55

3 Answers3

17

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);
}
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
0

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

  • I didn't have my hopes held high really...that's why I also asked for a VB6 format-string resource, because I figured I might have to re-write it. – Chris Pfohl Nov 01 '10 at 20:25
0

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
Joel Mueller
  • 28,324
  • 9
  • 63
  • 88
  • I don't see how this code would work. In VB6 format string `dd-mm-yy hh:mm:ss`, the first `mm` is months and the second `mm` is minutes. For .Net they both are minutes. It does not account for escaped literals and for quoted literals either. – GSerg Jul 29 '20 at 12:42