views:

209

answers:

0

Hello all,

I am in the process of trying to create a macro that will, through a combination of code and Regular Expressions, clean-up and apply consistant formatting to our library of SQL Scripts.

My macro consists of 2 parts. The first section loops through a collection of SQL key words (select, from, where, etc..) and uses the Find object to perform a Find / Replace All and convert all keywords to UPPERCASE.

Ex:

    //Create list of literal string changes
    Dim literals As New Dictionary(Of String, String)
    With literals
        .Add("and", "AND")
        .Add("as", "AS")
        .Add("begin", "BEGIN")
        .Add("between", "BETWEEN")
        //
        //other keywords go here...
        //
        .Add("select", "SELECT")
        .Add("set", "SET")
        .Add("where", "WHERE")
        .Add("with", "WITH")
    End With

    Dim f As Find = DTE.Find
    With f
        .Action = vsFindAction.vsFindActionReplaceAll
        .Target = vsFindTarget.vsFindTargetCurrentDocument
        .PatternSyntax = vsFindPatternSyntax.vsFindPatternSyntaxLiteral
        .ResultsLocation = vsFindResultsLocation.vsFindResultsNone
        .MatchCase = False
        .MatchWholeWord = True
        .Backwards = False
        .MatchInHiddenText = False
    End With
    For Each entry As KeyValuePair(Of String, String) In literals
        f.FindWhat = entry.Key
        f.ReplaceWith = entry.Value
        f.Execute()
    Next

Once this is finished, I loop through a second collection containing FindWhat and ReplaceWith regular expressions for anything more complex (such as ensuring that the body of all IF statements are wrapped in BEGIN / END blocks

Ex:

    Dim expressions As New Dictionary(Of String, String)()
    With expressions
        //Find any spaces or tabs preceding a comma and zero or more spaces at the end of a line
        //Strip all spaces / tabs, leaving just the comma
        .Add(":b+,:b*$", ",")

        //Find any comma that follows the beginning of a new line preceded by 0 or more spaces/ tabs
        //Move the comma before the new-line, keep the same number of spaces / tabs after the new-line
        .Add("\n{:b*},", ",\n\1")

        //Find any instance of an IF statement not followed by a BEGIN / END block
        //Wraps the line following the IF statement in a BEGIN / END block
        .Add("^{:b*IF(.*)\n}{:b*}<~(BEGIN){(.*)}\n", "\1\2BEGIN\n\2\t\3\n\2END")

        //Find any INSERT statement (INTO clause optional) that has following text on the same line
        //Move the text following the INSERT statement down a line and indent it
        .Add("^{:b*}INSERT:b*(INTO)*:b*{(.*)}\n", "\1INSERT INTO\n\1\t\2\n")

        //Find any SELECT statement (DISTINCT clause optional) that has following text on the same line
        //Move the text following the SELECT statement down a line and indent it
        .Add("^{:b*}{SELECT (DISTINCT)*}:b*{(.+)}\n", "\1\2\n\1\t\3\n")

        //Finds any instance of a JOIN clause split onto seperate lines
        //puts the JOIN clause on a single line 
        .Add("{(INNER|LEFT|OUTER|RIGHT)}:b*(\n:b*)+JOIN", "\1 JOIN")

        //Finds any instance of any default JOIN clause missing its INNER prefix
        //adds the INNER prefix
        .Add("~(INNER|LEFT|OUTER|RIGHT){:b+}JOIN", "\1INNER JOIN")

        //more regular expressions go here...
    End With
    With f
        .Action = vsFindAction.vsFindActionReplaceAll
        .Target = vsFindTarget.vsFindTargetCurrentDocument
        .PatternSyntax = vsFindPatternSyntax.vsFindPatternSyntaxRegExpr
        .ResultsLocation = vsFindResultsLocation.vsFindResultsNone
        .MatchCase = False
        .MatchWholeWord = False
        .Backwards = False
        .MatchInHiddenText = False
    End With
    For Each entry As KeyValuePair(Of String, String) In expressions
        f.FindWhat = entry.Key
        f.ReplaceWith = entry.Value
        f.Execute()
    Next

This is my first foray into programming macros for use in Visual Studio, so any feedback / comments / suggestions on my approach would be greatly appreciated...