wake-up-neo.com

Speichern eines neuen Excel-Dokuments als makrofreie Arbeitsmappe ohne Aufforderung

Ich verwende Excel 2010. Ich habe eine Excel-Makro-aktivierte Vorlage, die eine Datenverbindung zu einer Textdatei hat, die so eingestellt ist, dass sie automatisch aktualisiert wird, wenn ein neues Dokument mit dieser Vorlage erstellt wird.

Das folgende Makro befindet sich im Objekt "ThisWorkbook", um die Datenverbindung vor dem Speichern des neuen Dokuments zu entfernen:

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)

    Do While ActiveWorkbook.Connections.Count > 0
        ActiveWorkbook.Connections.Item(ActiveWorkbook.Connections.Count).Delete
    Loop

End Sub

Wenn ein Benutzer auf das Speichersymbol klickt/Ctrl + S drückt, einen Dateinamen eingibt und dann auf Speichern klickt, um ihn als makrofreie Excel-Arbeitsmappe zu speichern (wie der standardmäßige und erforderliche Dateityp), wird eine Meldung mit der folgenden Meldung angezeigt:

Die folgenden Funktionen können nicht in makrofreien Arbeitsmappen gespeichert werden:

• VB Projekt

Um eine Datei mit diesen Funktionen zu speichern, klicken Sie auf Nein und wählen Sie dann eine Makro-aktivierter Dateityp in der Liste Dateityp.

Klicken Sie auf Ja, um das Speichern als makrofreie Arbeitsmappe fortzusetzen.

Kann verhindert werden, dass diese Nachricht angezeigt wird, und Excel davon ausgehen kann, dass der Benutzer mit einer makrofreien Arbeitsmappe fortfahren möchte?

Ich habe alles gesucht und habe verstanden, dass ich in der Lage bin, Code zu dem Arbeitsmappenobjekt hinzuzufügen, das sich selbst entfernt, so dass Excel kein VB -Projekt hat, um diese Nachricht auszulösen. Dies würde jedoch dazu führen, dass jeder Benutzer die Einstellungen für das Sicherheitscenter ändert ( Vertrauen Sie auf das VBA-Projektobjektmodell, das ich vermeiden möchte.

Ich habe auch Vorschläge zur Verwendung von gesehen:

Application.DisplayAlerts = False

aber kann das nicht zum Laufen bringen. Jedes Anwendungsbeispiel scheint in einem Sub zu sein, das auch das Speichern des Dokuments übernimmt. In meiner Situation endet das BeforeSave-Sub, bevor das Dokument in der voreingestellten Nicht-VBA-Methode gespeichert wird. Warum funktioniert es nicht?

Wird diese Eigenschaft auf einen Standardwert "True" zurückgesetzt, nachdem das Sub beendet wurde/bevor das Speichern tatsächlich durchgeführt wird?

Ich entschuldige mich für jeglichen Blödsinn, den ich gemacht habe, meine Erfahrung mit VBA ist sehr begrenzt.

13
Tom Turner

Anderer Ansatz ... Wenn die Vorlage geladen ist, muss der Benutzer als speichern (Ich habe eine Arbeitsmappe/Vorlage mit einer ähnlichen Situation ...). Dies sollte sie bis zum Ordner Dokumente des Benutzers öffnen. Sie können jedoch anpassen, um die Datei an einem beliebigen Ort zu speichern.

Fügen Sie im ThisWorkbook-Modul Folgendes ein:

Option Explicit

Private Sub Workbook_Open()
    Dim loc As Variant
    Application.DisplayAlerts = False
    loc = Application.GetSaveAsFilename(FileFilter:="Excel Files (*.xlsx), *.xlsx", Title:="Save As...", InitialFileName:="%USERPROFILE%\Documents\NAME_OF_FILE")
    If loc <> False Then
        ActiveWorkbook.SaveAs Filename:=loc, FileFormat:=51
        Exit Sub
    End If
    Application.DisplayAlerts = True
End Sub

Edit1: Hinzufügen der if-Anweisung unter Verwendung eines Basisvorlagennamens, sodass nachfolgende Speichern das Speichern unter nicht auffordern:

Option Explicit

Private Sub Workbook_Open()
    If ActiveWorkbook.Name = "_NAME_OF_FILE.xlsb" Then
        Dim loc As Variant
        Application.DisplayAlerts = False 
        loc = Application.GetSaveAsFilename(FileFilter:="Excel Files (*.xlsx), *.xlsx", Title:="Save As...", InitialFileName:="%USERPROFILE%\Documents\_NAME_OF_FILE")
        If loc <> False Then
            ActiveWorkbook.SaveAs Filename:=loc, FileFormat:=51
            Exit Sub
        End If
        Application.DisplayAlerts = True
    End If
End Sub
2
Cyril

Ich kann nicht auf Excel 2010 testen, aber zumindest für 2016 funktioniert es gut:

Sub SaveAsRegularWorkbook()

    Dim wb As Workbook
    Dim Path As String

    Set wb = ThisWorkbook
    Path = "T:\he\Path\you\prefer\"
    Application.DisplayAlerts = False
    Application.EnableEvents = False
    wb.SaveAs Filename:=Path & "Test.xlsx", FileFormat:=51
    Application.DisplayAlerts = True
    Application.EnableEvents = True

End Sub

Versuche es.

2
EarlyBird2

Für diese Antwort gehe ich davon aus, dass Sie mit einer makroaktivierten Excel-Vorlage eine xltm-Datei meinen. Ich vermute auch, dass Sie unter "neues Dokument" das Dokument verstehen, das generiert wird, wenn ein Benutzer auf die XTLM-Datei doppelklickt (daher hat diese neue Datei keinen Speicherort, da sie noch nicht gespeichert wurde). 

Um Ihr Problem zu lösen, können Sie ein custom SaveAs-Fenster (Application.GetSaveAsFilename) verwenden, um mehr Kontrolle darüber zu haben, wie der Benutzer die Datei speichert, wenn das Ereignismakro Workbook_BeforeSave aufgerufen wird.

So implementieren Sie es:

1 - Kopiere diesen Code in ein neues Modul. 

Option Explicit  

Sub SaveAsCustomWindow()  

    Const C_PROC_NAME As String = "SaveAsCustomWindow"
    Dim strFullFileName As String, strPreferedFolder As String, strDefaultName As String
    Dim UserInput1 As Variant, UserInput2 As Variant
    Dim isValidName As Boolean, isFileClosed As Boolean, isWorkbookClosed As Boolean
    Dim strFilename As String, strFilePath As String


    'To avoid Warning when overwriting
    Application.DisplayAlerts = False
    'Disable events (mostly for the BeforeSave event) to avoid creating infinite loop
    Application.EnableEvents = False
    On Error GoTo ErrHandler

    'Customizable section
    strDefaultName = ThisWorkbook.Name
    strPreferedFolder = Environ("USERPROFILE")

    Do While isWorkbookClosed = False
        Do While isFileClosed = False
            Do While isValidName = False
                UserInput1 = Application.GetSaveAsFilename(InitialFileName:=strPreferedFolder & "\" & strDefaultName, FileFilter:="Excel Workbook (*.xlsx),*.xlsx")

                If UserInput1 = False Then
                    GoTo ClosingStatements 'This is important to take care of the case when the user presses cancel
                Else
                    strFullFileName = UserInput1
                End If

                strFilename = Right(strFullFileName, Len(strFullFileName) - InStrRev(strFullFileName, "\"))
                strDefaultName = strFilename

                strFilePath = Left(strFullFileName, InStrRev(strFullFileName, "\") - 1)
                strPreferedFolder = strFilePath

                'If the file exist, ask for overwrite permission
                If Dir(strFullFileName) <> "" Then
                    UserInput2 = MsgBox(strFilename & " already exists." & vbNewLine & "Do you want to overwrite?", vbYesNoCancel Or vbExclamation)
                    If UserInput2 = vbNo Then
                        isValidName = False
                    ElseIf UserInput2 = vbYes Then
                        isValidName = True
                    ElseIf UserInput2 = vbCancel Then
                        GoTo ClosingStatements
                    Else
                        GoTo ClosingStatements
                    End If
                Else
                    isValidName = True
                End If
            Loop

            'Check if file is actually open
            If isFileOpen(strFullFileName) Then
                MsgBox "The workbook you want to overwrite is currently open. Choose a different name, or close the  workbook before saving.", vbExclamation
                isValidName = False
                isFileClosed = False
            Else
                isFileClosed = True
            End If
        Loop

        'Check if an opened workbook has the same name
        If isWorkbookOpen(strFilename) Then
            MsgBox "You cannot save this workbook with the same name as another open workbook or add-in. Choose a different name, or close the other workbook or add-in before saving.", vbExclamation
            isValidName = False
            isFileClosed = False
            isWorkbookClosed = False
        Else
            isWorkbookClosed = True
        End If
    Loop

    ThisWorkbook.SaveAs Filename:=strFullFileName, FileFormat:=xlOpenXMLWorkbook

ClosingStatements:
    Application.EnableEvents = True
    Application.DisplayAlerts = True
    Exit Sub
ErrHandler:
    Call MsgBox("Run-time error '" & Err.Number & "': " & Err.Description & vbNewLine & _
         "While running: " & C_PROC_NAME & IIf(Erl <> 0, vbNewLine & "Error Line: " & Erl, "")
    GoTo ClosingStatements

End Sub

Function isFileOpen(ByVal Filename As String) As Boolean

    Dim ff As Long, ErrNo As Long

    On Error Resume Next
    ff = FreeFile()
    Open Filename For Input Lock Read As #ff
    Close ff
    ErrNo = Err
    On Error GoTo 0

    Select Case ErrNo
        Case 0:    isFileOpen = False
        Case 70:   isFileOpen = True
    End Select

End Function

Function isWorkbookOpen(ByVal Filename As String) As Boolean

    Dim wb As Workbook, ErrNo As Long

    On Error Resume Next
    Set wb = Workbooks(Filename)
    ErrNo = Err
    On Error GoTo 0

    Select Case ErrNo
        Case 0:         isWorkbookOpen = True
        Case Else:      isWorkbookOpen = False
    End Select

End Function

Erklärung zu Teil 1 : Das Ganze mag ein wenig übertrieben erscheinen, aber die gesamte Fehlerbehandlung ist hier wichtig, um mögliche Fehler zu berücksichtigen und sicherzustellen, dass die Einstellung für Application.EnableEvents selbst dann auf TRUE zurückgesetzt wird, wenn ein Fehler auftritt . Andernfalls werden alle Ereignismakros in Ihrer Excel-Anwendung deaktiviert.

2 - Rufen Sie die SaveAsCustomWindow -Prozedur in der Workbook_BeforeSave-Ereignisprozedur folgendermaßen auf: 

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)

    'Your code

    If ThisWorkbook.Path = "" Then
        SaveAsCustomWindow
        Cancel = True
    End If

End Sub

Beachten Sie, dass wir die Variable Cancel = True setzen müssen, um zu verhindern, dass das standardmäßige SaveAs-Fenster angezeigt wird. Außerdem ist die if-Anweisung vorhanden, um sicherzustellen, dass das benutzerdefinierte SaveAs-Fenster nur verwendet wird, wenn für die Datei never gespeichert wurde.

1
DecimalTurn

Um Ihre Fragen zu beantworten:

Ist es möglich zu verhindern, dass diese Nachricht erscheint?

Ja, mit der Application.DisplayAlerts-Eigenschaft

Kann Excel davon ausgehen, dass der Benutzer mit einer makrofreien Arbeitsmappe fortfahren möchte?  

Nein, Sie müssen die Prozedur zum Speichern der Arbeitsmappe schreiben, das Excel-Ereignis SaveAs umgehen und die Arbeitsmappe mit der Benutzereingabe (Path & Filename) im erforderlichen Format speichern.

Das folgende Verfahren verwendet einen FileDialog, um den Pfad und den Dateinamen des Benutzers zu erfassen und speichert dann die Datei, ohne die Warnmeldung anzuzeigen. __ Ich habe einige erklärende Kommentare hinzugefügt, lassen Sie mich jedoch Ihre Fragen wissen.

Kopieren Sie diese Prozeduren in das Modul ThisWorkbook:

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
    Cancel = True       'Prevents repetitive Save
    Call Workbook_BeforeSave_ApplySettings_And_Save
    End Sub


Private Sub Workbook_BeforeSave_ApplySettings_And_Save()
Dim fd As FileDialog, sFilename As String

    Rem Sets FileDialog to capture user input
    Set fd = Application.FileDialog(msoFileDialogSaveAs)
    With fd
        .InitialView = msoFileDialogViewDetails
        .Title = vbNullString               'Resets default value in case it was changed
        .ButtonName = vbNullString          'Resets default value in case it was changed
        .AllowMultiSelect = False
        If .Show = 0 Then Exit Sub          'User pressed the Cancel Button
        sFilename = .SelectedItems(1)
    End With

    With ThisWorkbook

        Do While .Connections.Count > 0
            .Connections.Item(.Connections.Count).Delete
        Loop

        Application.EnableEvents = False                                'Prevents repetition of the Workbook_BeforeSave event
        Application.DisplayAlerts = False                               'Prevents Display of the warning message
        On Error Resume Next                                            'Prevents Events and Display staying disable in case of error
        .SaveAs Filename:=sFilename, FileFormat:=xlOpenXMLWorkbook      'Saves Template as standard Excel using user input
        If Err.Number <> 0 Then
            MsgBox "Run-time error " & Err.Number & String(2, vbLf) _
                & Err.Description & String(2, vbLf) _
                & vbTab & "Process will be cancelled.", _
                vbOKOnly, "Microsoft Visual Basic"
        End If
        On Error GoTo 0
        Application.DisplayAlerts = True
        Application.EnableEvents = True

    End With

    End Sub
0
EEM