Макрос работает в Excel 2003, а не в 2007

У меня есть макрос, который экспортирует книгу, которая отлично работает (и работала годами) в Excel 2003. Однако она не работает ни на одной машине с 2007 или 2010. Она запускается и открывает окно Save As, несмотря ни на что Я печатаю, когда я нажимаю ОК, он просто сидит там. Нажатие Ok для сохранения ничего не делает. Может кто-нибудь помочь, пожалуйста?

Код:

Sub ExportReports()

Dim fdialog As Office.FileDialog
Dim varfile As String

Static varfile_name As String
Dim curr_wb_name As String
Dim num_sheets As Integer
Dim xflag As String
Dim openflag As Boolean
Static strpassword As String


'check to see if invoice has been moved
'check to see if all programs report has been moved
'move specified report


'User selects the file containing the budget - must be in set format
'Changes to the format of budget spreadsheet are likely to affect this code

curr_wb_name = ActiveWorkbook.Name
prog_name = ActiveWorkbook.Worksheets("Menu").Range("F14")

lineselectfile: 
Set fdialog = Application.FileDialog(msoFileDialogFilePicker)

With fdialog
    .Title = "Please select or create the file you wish to export reports to"
    .Filters.Clear
    .Filters.Add "Microsoft Excel Files", "*.xlsx"

    If .Show = True Then
        varfile = .SelectedItems(1)
    Else
    Exit Sub
        'MsgBox "You must select a file to import, please try again", _
        '        vbOKOnly, "Import Error!"
        'GoTo lineselectfile
    End If
End With

If strpassword = "" Then
   strpassword = InputBox("Enter a password to protect worksheets in this file")
End If

n = 0
For n = 1 To Workbooks.Count
   If Workbooks(n).Name = varfile_name Then
     openflag = True
     Workbooks(n).Activate
   End If
Next

If openflag = False Then
   Workbooks.Open Filename:=varfile, UpdateLinks:=0
End If

varfile_name = ActiveWorkbook.Name
num_sheets = Workbooks.Count
'n = 0
xflag = "a"
'Do Until n = num_sheets
If Sheets(1).Name = "Invoice" Then
   xflag = xflag & "b"
End If
If Sheets(2).Name = "All Programs" Then
   xflag = xflag & "c"
End If
'n = n + 1
'Loop

Select Case xflag
Case "a" ' Both Invoice and All Programs must be exported
    Windows(curr_wb_name).Activate
    Sheets("Invoice").Select
    Sheets("Invoice").Copy before:=Workbooks(varfile_name).Sheets(1)
    Cells.Select
    Selection.Copy
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False _
    , Transpose:=False
    ActiveSheet.Protect Password:=strpassword, Scenarios:=True
    Range("a1").Select
    Windows(curr_wb_name).Activate
    Sheets("Preview All Programs").Select
    Sheets("Preview All Programs").Copy before:=Workbooks(varfile_name).Sheets(2)
    Cells.Select
    Selection.Copy
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False _
    , Transpose:=False
    Sheets("Preview All Programs").Name = "All Programs"
    ActiveSheet.Protect Password:=strpassword, Scenarios:=True
    Range("a1").Select
Case "ab" ' Only All Programs must be exported
    Windows(curr_wb_name).Activate
    Sheets("Preview All Programs").Select
    Sheets("Preview All Programs").Copy After:=Workbooks(varfile_name).Sheets(2)
    Cells.Select
    Selection.Copy
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False _
    , Transpose:=False
    Sheets("Preview All Programs").Name = "All Programs"
    ActiveSheet.Protect Password:=strpassword, Scenarios:=True
    Range("a1").Select
Case "ac" ' Only invoice must be exported
    Windows(curr_wb_name).Activate
    Sheets("Invoice").Select
    Sheets("Invoice").Copy After:=Workbooks(varfile_name).Sheets(1)
    Cells.Select
    Selection.Copy
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False _
    , Transpose:=False
    ActiveSheet.Protect Password:=strpassword, Scenarios:=True
    Range("a1").Select

End Select
    Windows(curr_wb_name).Activate
    Sheets("Preview").Select
    Sheets("Preview").Copy After:=Workbooks(varfile_name).Sheets(2)
    Cells.Select
    Selection.Copy
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False _
    , Transpose:=False
    Sheets("Preview").Name = prog_name
    ActiveSheet.Protect Password:=strpassword, Scenarios:=True
    Range("a1").Select
    Windows(curr_wb_name).Activate
    Worksheets("Menu").Activate
    'Workbooks(varfile_name).Close

End Sub

person Maz    schedule 13.12.2011    source источник


Ответы (1)


Там много кода, но только одна вещь бросается в глаза относительно изменений в Excel 2007. В 2003 году, если вы копировали лист в другое место, он становился ActiveSheet. Этого не происходит в версии 2007+, поэтому вам нужно переработать свой код, чтобы явно ссылаться на копию.

Eg:

Dim shtCopy as Worksheet

'copy a sheet
ThisWorkbook.Sheets("Template").Copy After:=Thisworkbook.Sheets("Data")
'get a reference to the copy
Set shtCopy = ThisWorkbook.Sheets(Thisworkbook.Sheets("Data").Index+1)

Изменить: вы действительно имеете в виду это

num_sheets = Workbooks.Count

и не

num_sheets = ActiveWorkbook.Sheets.Count

?

РЕДАКТИРОВАТЬ: насколько я могу предположить, это должно сработать для вас

Sub ExportReports()

    Static varfile_name As String
    Static strpassword As String

    'Dim fdialog As Office.FileDialog
    Dim varfile As String
    Dim prog_name As String
    Dim curr_wb As Workbook
    Dim selected_wb As Workbook

    Dim xflag As String
    Dim n As Integer

    Set curr_wb = ActiveWorkbook
    prog_name = curr_wb.Worksheets("Menu").Range("F14")

    'Set fdialog = Application.FileDialog(msoFileDialogFilePicker)
    With Application.FileDialog(msoFileDialogFilePicker)
        .Title = "Please select or create the file you wish to export reports to"
        .Filters.Clear
        .Filters.Add "Microsoft Excel Files", "*.xlsx"
        If .Show = True Then
            varfile = .SelectedItems(1)
        Else
            Exit Sub
        End If
    End With

    If strpassword = "" Then
       strpassword = InputBox("Enter a password to protect worksheets in this file")
    End If

    'tw Not sure what the purpose of this is?
    '  by default it will select the *previous* selected wb...
    For n = 1 To Application.Workbooks.Count
       If Workbooks(n).Name = varfile_name Then
         Set selected_wb = Workbooks(n)
         Exit For 'break out of loop
       End If
    Next

    If selected_wb Is Nothing Then
       Set selected_wb = Workbooks.Open(Filename:=varfile, UpdateLinks:=0)
    End If

    varfile_name = selected_wb.Name
    xflag = "a"
    If selected_wb.Sheets(1).Name = "Invoice" Then
       xflag = xflag & "b"
    End If
    If selected_wb.Sheets(2).Name = "All Programs" Then
       xflag = xflag & "c"
    End If

    Select Case xflag
    Case "a" ' Both Invoice and All Programs must be exported

        CopySheet curr_wb.Sheets("Invoice"), _
                  selected_wb, 1, "", strpassword

        CopySheet curr_wb.Sheets("Preview All Programs"), _
                  selected_wb, 2, "All Programs", strpassword

    Case "ab" ' Only All Programs must be exported

        CopySheet curr_wb.Sheets("Preview All Programs"), _
                  selected_wb, 3, "All Programs", strpassword

    Case "ac" ' Only invoice must be exported

        CopySheet curr_wb.Sheets("Invoice"), _
                  selected_wb, 2, "", strpassword

    End Select

    CopySheet curr_wb.Sheets("Preview"), _
                  selected_wb, 3, prog_name, strpassword


    curr_wb.Activate
    curr_wb.Worksheets("Menu").Activate

    'selected_wb.Close

End Sub

'Copy sheet to specific position, convert to values,
'  change name
Sub CopySheet(wsToCopy As Worksheet, destWb As Workbook, _
              destPos As Integer, newName As String, pw As String)
    Dim shtCopy As Worksheet

    If destPos = 1 Then
        wsToCopy.Copy Before:=destWb.Sheets(1)
    Else
        wsToCopy.Copy After:=destWb.Sheets(destPos - 1)
    End If
    With destWb.Sheets(destPos)
        .UsedRange.Value = .UsedRange.Value
        If Len(newName) > 0 Then .Name = newName
        .Protect Password:=pw, Scenarios:=True
        .Range("A1").Select
    End With
End Sub
person Tim Williams    schedule 14.12.2011
comment
Спасибо за ответ. Человек, который делал для нас, ушел много лет назад, и никто толком ничего не знает о коде. Где в коде я мог бы разместить ваше предложение, чтобы увидеть, работает ли оно? - person Maz; 14.12.2011
comment
@user: если вы хотите отправить мне книгу, я постараюсь исправить ее для вас. t i m j w i l l i a m s {at} g ma i l {.com} - person Tim Williams; 14.12.2011
comment
Спасибо за мысль, но я не могу этого сделать из соображений конфиденциальности. Я попытался удалить всю конфиденциальную информацию, но 90% контента связано с другими книгами/бюджетами/базами данных, и если я уберу это, все просто выйдет из строя и не будет работать. - person Maz; 14.12.2011
comment
+1 согласен с Иссуном, хорошая работа. @user1096768 user1096768, вы можете разорвать ссылки на все ваши входные книги с помощью данных .. Изменить ссылки, это может упростить очистку вашей книги для публикации - person brettdj; 14.12.2011
comment
Спасибо за усилия, это очень ценится. Я скопировал отредактированный код, и то же самое. Никаких ошибок или чего-то еще, просто когда я нажимаю ОК в окне сохранения, ничего не происходит. Можно нажать 10 раз и ничего, просто нужно отменить, чтобы выйти из него. Любые другие идеи? еще раз спасибо! - person Maz; 15.12.2011
comment
Когда вы говорите окно сохранения, вы имеете в виду диалоговое окно файла? У меня работает нормально, но я только пытался открыть существующий файл, а не создавать новый. Попробуйте установить точку останова в коде, а затем выполните ее. в противном случае, я не знаю, что еще предложить. - person Tim Williams; 15.12.2011
comment
Извините, я понятия не имею, что такое файловый диалог. Но под полем «Сохранить» я подразумеваю окно «Сохранить как» проводника Windows (где вы можете просматривать папки, чтобы найти каталог, в который хотите сохранить), а затем нажмите «ОК», чтобы сохранить файл. Нажатие ок ничего не делает. очень странный. - person Maz; 23.12.2011
comment
Диалоговое окно файла — это то, что запускает Application.FileDialog(msoFileDialogFilePicker): это то, как вы выбираете файл, в который хотите скопировать указанные рабочие листы. У меня работает нормально: я понятия не имею, что происходит с вашей настройкой. - person Tim Williams; 23.12.2011