2015-06-22 16 views
5

In risposta alla this domanda ho pensato che sarebbe stato divertente scrivere una macro VBE che dovrebbe sostituire automaticamente le linee che sembranometodo ReplaceLine in VBE sostituire solo una parte della linea di

DimAll a, b, c, d As Integer 

da

Nella mia prima bozza voglio solo modificare una singola riga selezionata. Dopo aver stabilito i relativi riferimenti per arrivare al modello VBE oggetto (vedi http://www.cpearson.com/excel/vbe.aspx) e giocare un po 'mi si avvicinò con:

Function ExpandDim(codeLine As String) As String 
    Dim fragments As Variant 
    Dim i As Long, n As Long, myType As String 
    Dim last As Variant 
    Dim expanded As String 

    If UCase(codeLine) Like "*DIMALL*AS*" Then 
     codeLine = Replace(codeLine, "dimall", "Dim", , , vbTextCompare) 
     fragments = Split(codeLine, ",") 
     n = UBound(fragments) 
     last = Split(Trim(fragments(n))) 
     myType = last(UBound(last)) 
     For i = 0 To n - 1 'excludes last fragment 
      expanded = expanded & IIf(i = 0, "", ",") & fragments(i) & " As " & myType 
     Next i 
     expanded = expanded & IIf(n > 0, ",", "") & fragments(n) 
     ExpandDim = expanded 
    Else 
     ExpandDim = codeLine 
    End If 
End Function 

Sub DimAll() 
    Dim myVBE As VBE 
    Dim startLine As Long, startCol As Long 
    Dim endLine As Long, endCol As Long 
    Dim myLine As String 
    Set myVBE = Application.VBE 
    myVBE.ActiveCodePane.GetSelection startLine, startCol, endLine, endCol 
    myLine = myVBE.ActiveCodePane.CodeModule.Lines(startLine, 1) 
    Debug.Print ExpandDim(myLine) 
    myVBE.ActiveCodePane.CodeModule.ReplaceLine startLine, ExpandDim(myLine) 
End Sub 

In un altro modulo di codice che ho avuto:

Sub test() 
    DimAll a, b, c, d As Integer 
    Debug.Print TypeName(a) 
    Debug.Print TypeName(b) 
    Debug.Print TypeName(c) 
    Debug.Print TypeName(d) 
End Sub 

Questo è il parte strana. Quando ho evidenziare la riga che inizia DimAll una, e invoco il mio goffamente chiamato sub DimAll, nella finestra immediata che vedo

che è come previsto, ma nel modulo di codice stesso la linea viene modificato in

Dim a, b, c, d As Integer 

DimAll è stato sostituito da Dim, ma il resto della riga non è stato modificato. Sospetto che le virgole stiano confondendo il metodo ReplaceLine. Qualche idea su come risolvere questo problema?

+4

1. Fate attenzione con la modifica del ActiveCodePane. Ho solo modificato per errore il codice che stava modificando ... Per ulteriori informazioni su questo, ti consiglio di postare su http://codereview.stackexchange.com/ Il VBIDE è un'ossessione per me. Sarei felice di aiutarti a perfezionare questo lassù. 2. Potresti voler vedere [questo] (https://github.com/rubberduck-vba/Rubberduck/wiki/MultipleDeclarationsInspection) che fa parte di [questo] (https://github.com/rubberduck-vba/Rubberduck). (Disclaimer: I'm one of the devs.) – RubberDuck

+0

@RubberDuck Penso che [questo snippet sia più strettamente correlato a ciò che OP sta facendo] (https://github.com/rubberduck-vba/Rubberduck/blob/next/RetailCoder .VBE/Inspections/VariableTypeNotDeclaredInspectionResult.cs # L28-L46) –

+0

@RubberDuck Questa era principalmente la dimostrazione del concetto. Ha sicuramente bisogno di essere lucidato. Per prima cosa, probabilmente nessuno scrive Dim a, b, c, d As Integer con l'intenzione di dichiarare a, b, c come varianti. Avrebbe più senso saltare quella parte su DimAll e semplicemente espandere tutte le cose che assomigliano a Dim a, b, c, d As Integer nell'intero progetto. In definitiva, mi piacerebbe capire come trasformarlo in un componente aggiuntivo VBE con le scorciatoie da tastiera. Vedrò quel collegamento –

risposta

4

Quando si esegue con il debugger, myLine modifica il valore tra le due chiamate. Il DimAll diventa Dim alla seconda volta.

Questo perché si sostituisce il valore di codeLine dopo aver inserito il condizionale If all'interno dello ExpandDim Function.

creare una nuova variabile in quella funzione e si dovrebbe andare bene ... o passarlo ByVal e il gioco è fatto:

Function ExpandDim(ByVal codeLine As String) As String 
+0

Vedo - era un errore semplice di Ref (la mia funzione ExpandDim ha avuto un effetto collaterale). Il problema viene risolto anche se inserisco il modificatore byVal prima dell'argomento in quella definizione di funzione.Non ho quasi esperienza di scripting del VBE, quindi sospetto un profondo fraintendimento del suo modello di oggetti da parte mia piuttosto che un semplice problema di semantica passante. Grazie. –