Страницы: 1
RSS
Копирование листов с помощью кода VBA, Исключение ошибок при копировании листов
 

Есть книга эксель — Акты . В книге Акты имеются 1 лист и 1 модуль (module1.bas). В модуле имеется функция GetStringA, возвращающая строковый результат (функция описана как As String). Функция имеет параметр (параметр описан как As Integer). На листе эта функция используется: в функцию подаются числа с 1 по 5. Так же функция используется в коде листа. Функция выдаёт результат. Всё казалось бы хорошо. Ранее копировал листы из текущей книги кодом VBA в новую книгу с помощью команды Sheets("4-й акт").Copy. После копирования работа книгой Акты прекращалась (книга закрывалась так же кодом VBA). Сейчас возникла необходимость после копирования листа в новую книгу, сохранить новую книгу и продолжить работу над книгой Акты.

Сейчас с помощью кода

Код
        With ActiveWorkbook.VBProject.VBComponents(ActiveSheet.CodeName).CodeModule
            .DeleteLines 1, .CountOfLines
        End With

я удаляю весь код в новой книге (код с модуля листа). Формулы превращаю в значения с помощью кода

Код
        With ActiveWorkbook.Sheets("4-й акт")
            .Cells.Copy
            .Range("A1").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
        End With

Сохранение книги в формате .xlsb происходит с помощью кода

Код
ActiveWorkbook.SaveAs FileName:=stFile, FileFormat:=xlExcel12, CreateBackup:=False

где stFile — путь к файлу (M:\Акты\П\4 Апрель\À¹479.xlsb).

На этом этапе пока тоже всё хорошо.

А вот сразу после сохранения обращаюсь к переменной Err. Её значение становится равным 40040. А на листе в ячейках, в которых вызывалась функция GetStringA, появляется ошибка #ЗНАЧ!/

Кто из знающих подскажет: как правильно, с помощью кода VBA, копировать листы в новую книгу, при условии, что как на листе (формулами эксель), так и в коде VBA идёт использование функций, описанных в модуле (module1.bas). При этом, код, который есть в модуле листа, далее не нужен, так как будут только сами данные, а не вычисления (формулы будут заменены на значения). Так же не нужен модуль (module1.bas).

Изменено: offorder - 10.04.2026 13:41:37
 
Код
Sub myCopy()
    Dim shSource As Worksheet
    Set shSource = Sheets("4-й акт")
    
    Dim shTarget As Worksheet
    shSource.Copy
    Set shTarget = ActiveSheet
    
    shTarget.UsedRange.Value = shSource.UsedRange.Value
    
    With ActiveWorkbook.VBProject.VBComponents(ActiveSheet.CodeName).CodeModule
        .DeleteLines 1, .CountOfLines
    End With
End Sub
 
МатросНаЗебре, так и что же тут нового? Ошибка-то не исчезнет. Как сделать так, чтобы её не было? В этом был весь вопрос.
 
Цитата
написал:
Ошибка-то не исчезнет.
Пробовали? Или предполагаете?
В этом варианте не должно быть ошибки, вызванной использованием пользовательской функции GetStringA.

О высказываниях:
Скрытый текст
Изменено: МатросНаЗебре - 10.04.2026 14:56:48
 
МатросНаЗебре, так у вас код не выполнит сохранение. А ошибка происходит именно при сохранении.
Конечно, в вашем коде ошибки не будет. Но если вставить команду сохранения, то ошибка появится. Каким образом её избежать?
 
Цитата
offorder написал:
где stFile — путь к файлу (M:\Акты\П\4 Апрель\À¹479.xlsb).
Вас ничего не смущает? Присмотритесь лучше сами к имени сохранённой книге! Есть там  какие-то непонятные символы?
 
В целом: нашёл, откуда ноги растут.
В самом начале процедуры сохранения выполняется такой код:
Код
    With Application
        .DisplayAlerts = False
        xlCalcMode = .Calculation
        xlRefStyle = .ReferenceStyle
        .Calculation = xlCalculationManual
        .ReferenceStyle = xlA1
        .ScreenUpdating = False
        .EnableEvents = False
    End With
После выполнения этого кода выполняется команда:
Код
    With ActiveWorkbook
        ...
        .SaveAs FileName:=stFolderName & stFileName, FileFormat:=xlExcel12, CreateBackup:=False
        ...
    End With
Она и вызывает ошибку.
Разумеется, в конце процедуры сохранения выполняется такой код:
Код
    With Application
        .DisplayAlerts = True
        .Calculation = xlCalcMode
        .ReferenceStyle = xlRefStyle
        .ScreenUpdating = True
        .EnableEvents = True
    End With


Решение проблемы связано с тем, чтобы снять галочку, а затем вернуть её в прежнее состояние в окне Параметры Excel, на вкладке Формулы, в разделе Параметры вычислений, пункт "Пересчитывать книгу перед сохранение" с помощью команд:
Код
    With ActiveWorkbook
        ...
        If Application.CalculateBeforeSave Then
            Application.CalculateBeforeSave = False
            .SaveAs FileName:=stFolderName & stFileName, FileFormat:=xlExcel12, CreateBackup:=False
            Application.CalculateBeforeSave = True
        Else
            .SaveAs FileName:=stFolderName & stFileName, FileFormat:=xlExcel12, CreateBackup:=False
        End If
        ...
    End With
Таким образом не происходит пересчёта книги перед сохранением, а именно пересчёт книги и вызывал ошибку.
Может, кому-то поможет.
Изменено: offorder - 15.04.2026 23:39:13
 
МатросНаЗебре, и да, делать такие присвоения ни к чему. Они никак не помогают в решении проблемы. Ваш анекдот - это из другой оперы. Отчасти вас понимаю: у вас было недостаточно данных.
 
offorder, Вы бы для начала полный код приводили, а не куски кодов. Тогда и решение могло быть предложено полное и правильное. А по кускам кода, помимо которых есть еще куча чего-то как выясняется - решать проблему неблагодарное занятие.
Код от МатросНаЗебре рабочий и не должен выдавать ошибку вычислений, т.к. в итоговом листе их нет(данные копируются как значения из исходного листа). Да, нет и сохранения - но так Вы ведь и не привели весь код, чтобы понять, где это сохранение вообще происходит и что до и после происходит тоже никто не знает.
Изменено: Дмитрий(The_Prist) Щербаков - 16.04.2026 08:49:43
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
Страницы: 1
Читают тему
Наверх