2016-06-02 8 views
2

Ich habe eine Liste von Excel-Dateien in einer Tabelle. Ich möchte sie durchschleifen und jedem ein Arbeitsblatt-Ereignis hinzufügen. Speichern Sie es, schließen Sie es und gehen Sie zum nächsten über. Das Problem ist, dass wenn ich die Arbeitsmappe erneut öffne (manuell), der Code weg ist.Programmatisch hinzufügen Arbeitsmappe Ereignis und speichern Sie es

Innerhalb der für jede Schleife:

Set xl = Workbooks.Open(filepath) 
addCode xl 'subroutine to add code 
xl.Save 
xl.Close SaveChanges:=False 

Die AddCode Unterprogramm ist:

Sub addCode(book As Excel.Workbook) 
    acsh = book.ActiveSheet.CodeName 
    startline = book.VBProject.VBComponents(acsh).CodeModule.CreateEventProc("SelectionChange", "Worksheet") + 1 
    book.VBProject.VBComponents(acsh).CodeModule.InsertLines startline, codetoadd 
End Sub 

Wenn ich kommentieren Sie xl.Close der Code in der Arbeitsmappe und arbeitet. Ich kann die Datei manuell speichern und schließen und der Code bleibt erhalten. Ich habe einen Unterbrechungspunkt zwischen xl.save und xl.close hinzugefügt und eine Kopie der Datei gemacht. Nachdem der Code fertig ist, hat keiner die Änderungen. Ich habe versucht, xl.saveas und xl.close SaveChanges: = True. Alle haben identische Ergebnisse.

Ich benutze Excel 2013, ich habe Excel gesagt, um den Zugriff auf das VBA-Objektmodell zu vertrauen. Ich habe versucht, XLS-Dateien und XLSM-Dateien zu verwenden. Natürlich funktioniert XLSX nicht.

+0

Es klingt wie Excel nicht erkennt, dass die Datei * schmutzig * ist, so das Speichern nicht denkt, dass es etwas zu tun? Haben Sie versucht, vor dem Speichern eine Zeile hinzuzufügen, die eine andere Eigenschaft ändert? Das könnte Excel veranlassen, die Datei als fehlerhaft zu betrachten. – ThunderFrame

+2

Die * dirty * -Flagge ist hier: 'ThisWorkbook.Saved = False' (lesbar und beschreibbar). Aber ich glaube nicht, dass das das Problem ist. Sind die Arbeitsmappen, die Sie öffnen, ".xlsx" oder sind sie ".xlsm"? Wenn sie '.xlsx' sind, wird der gesamte VBA-Code automatisch abgeschnitten. Normalerweise wird jedoch eine Warnung angezeigt, dass der gesamte Code entfernt wird (beim Versuch, die Datei zu speichern). – Ralph

+0

Ich habe gerade xl.saved = false vor dem Speichern hinzugefügt, das gleiche Problem. Es wurde das geänderte Dateidatum aktualisiert, also nehme ich an, dass es die ganze Zeit gespeichert hat. Ich habe xlsm und xls verwendet, ich erwarte nicht, dass xlsx funktioniert, also habe ich es nie versucht. – drew

Antwort

2

Hier ist ein Beispielcode, die für mich auf Excel 2010. Die Änderungen, die ich gemacht zu Ihrem Beispiel-Code arbeitet, sind:

  • Verwendung ein XLSM für das Arbeitsmappe Ziel - ich weiß, du dir schon gesagt, Tat dies.

  • Referenzieren Sie ein bestimmtes Arbeitsblatt in der AddCode-Sub, anstatt den Blattnamen von ActiveSheet abzurufen.

  • die Arbeitsmappe schmutzig Status pro Ralphs Kommentar

    gesetzt
  • Stellen Sie den Savechanges Flag, wenn die Arbeitsmappe Ziel Schließen

Other than that, ist meine Version zu Ihnen ziemlich ähnlich. Ich denke, dass es die Linie ist, die den Trick macht, d. H. Die schmutzige Flagge. Ich habe versucht, die SaveAs Methode auf dem VBProject selbst zu verwenden, der denkt, dass es dasselbe sein würde wie das Drücken der Speichern-Schaltfläche, wenn Sie im VBA-Editor selbst sind. Dies ergibt jedoch nur wenig hilfreiche Fehler.

Hier ist der Beispielcode:

Option Explicit 

Sub Test() 

    Dim wbTarget As Workbook 
    Dim strCode As String 

    ' get target workbook 
    Set wbTarget = Workbooks.Open("\\server\path\Book3.xlsm") 

    ' test setting code to worksheet change 
    strCode = "Debug.Print ""Sheet selection changed to: "" & Target.Address" 
    AddWorksheetChangeCode wbTarget, "Sheet1", strCode 

    ' test saving the target workbook 
    With wbTarget 
     ' set book to dirty to force the save 
     .Saved = False 
     .Save 
     .Close 
    End With 

End Sub 

Sub AddWorksheetChangeCode(ByRef wb As Workbook, strWorksheetName As String, strCode As String) 

    Dim intInsertLine As Integer 

    ' create stub for event and get line to insert 
    intInsertLine = wb.VBProject.VBComponents(strWorksheetName).CodeModule.CreateEventProc("SelectionChange", "Worksheet") + 1 

    ' add event logic 
    wb.VBProject.VBComponents(strWorksheetName).CodeModule.InsertLines intInsertLine, strCode 

End Sub 
+0

Zuerst habe ich Ihren Code versucht, funktioniert, perfekt! Dann versuchte ich herauszufinden, warum. Das Sicherungs-Flag (bei .close) und das .saved = false scheinen nicht wichtig zu sein. Sobald ich acsh = "Sheet1" von book.ActiveSheet.CodeName geändert hat, funktionierte es. Ich probierte das Sub und versuchte jedes Mal, wenn es funktionierte, in das Sub zu gehen, wenn es hart codiert war, sonst funktionierte es nicht. Die Sache, die ich nicht verstehe, ist warum, denn book.ActiveSheet.CodeName ist "Sheet1" (ich habe es überprüft). Eine Sache für jeden, der versucht, den Code zu verwenden. VBComponents() verwendet den Codenamen, der mit dem Blattnamen identisch sein kann oder nicht. – drew

Verwandte Themen