Вопрос или проблема
Предположим, у меня есть две книги (workbook1 и workbook2), мне нужно скопировать лист из workbook1 в workbook2.
Название скопированного листа, например, “Board”, содержит (ActiveX Controls), которые ссылаются на подпрограммы с назначенными макросами,
также скопированный лист имеет фигуры, такие как (Закругленный прямоугольник, Октагон), которые ссылаются либо на значение ячейки, либо на подпрограммы с назначенными макросами,
также скопированный лист имеет Диаграммы, которые ссылаются на диапазон ячеек.
Проблема со скопированным листом заключается в том, что все подпрограммы и формулы все еще ссылаются на (workbook1).
Поэтому мне нужно изменить скопированный лист, чтобы все ссылки на подпрограммы и формулы относились к (workbook2).
Я использовал следующий макрос, и он успешно работает только для копирования листа и изменения (ActiveX Controls) подпрограмм с назначенными макросами.
Но с другими фигурами (Закругленный прямоугольник, Октагон и т.д.) я получил
Ошибка времени выполнения ‘438’: Объект не поддерживает это свойство или метод
в этой строке If shp.Formula <> "" Then
А код для изменения диаграмм не дает эффекта (без поднятия ошибок).
Option Explicit
Option Compare Text
Sub Copy_Sheet_to_another_Workbook() 'Предполагает, что этот код находится в Workbook1 (ThisWorkbook)
Dim srcWs As Worksheet
Dim dstWb As Workbook
Dim dstWs As Worksheet
Dim shp As Shape
Dim srcWbName As String
Dim dstWbName As String
With Application
.Calculation = xlCalculationManual
.ScreenUpdating = False
.EnableEvents = False
.DisplayAlerts = False
End With
Set srcWs = ThisWorkbook.Sheets("Board") 'название листа для копирования
Set dstWb = Workbooks.Open("C:\Users\xxx\Desktop\Workbook2.xlsb") 'целевой Workbook
srcWs.Copy Before:=dstWb.Sheets(1)
Set dstWs = dstWb.Sheets(2)
srcWbName = ThisWorkbook.name
dstWbName = dstWb.name
'Обновление ссылок VBA на макросы/подпрограммы в фигурах с назначенными макросами
For Each shp In dstWs.Shapes
If shp.OnAction <> "" Then
If InStr(1, shp.OnAction, srcWbName, vbTextCompare) > 0 Then
shp.OnAction = Replace(shp.OnAction, srcWbName, dstWbName)
End If
End If
Next shp
'Обновление фигур с ссылками на ячейки в формуле
For Each shp In dstWs.Shapes
If shp.Formula <> "" Then
If InStr(1, shp.Formula, srcWbName, vbTextCompare) > 0 Then
shp.Formula = Replace(shp.Formula, srcWbName & "!", dstWbName & "!")
End If
End If
Next shp
'Обновление ссылок на диаграммы
For Each chartObj In dstWs.ChartObjects
With chartObj.Chart
Dim srs As Series
For Each srs In .SeriesCollection
If InStr(1, srs.Formula, srcWbName, vbTextCompare) > 0 Then
srs.Formula = Replace(srs.Formula, srcWbName & "!", dstWbName & "!")
End If
Next srs
End With
Next chartObj
dstWb.Activate
With Application
.Calculation = xlCalculationAutomatic
.ScreenUpdating = True
.EnableEvents = True
.DisplayAlerts = True
End With
End Sub
Ответ или решение
Копирование листа из одной книги в другую и модификация всех ссылок, включая ActiveX элементы, графики и диаграммы, может стать настоящим вызовом. Ваша задача, как разработчика, заключается не только в реализации копирования, но и в тонкой подстройке ссылок, чтобы они корректно работали в новой книге. Для справки, ниже представлен детализированный код, который поможет в решении данной проблемы, а также объяснение, как устранить ошибки и оптимизировать вашу работу.
Решение задачи
Option Explicit
Option Compare Text
Sub Copy_Sheet_to_another_Workbook()
Dim srcWs As Worksheet
Dim dstWb As Workbook
Dim dstWs As Worksheet
Dim shp As Shape
Dim chartObj As ChartObject
Dim srs As Series
Dim srcWbName As String
Dim dstWbName As String
' Отключаем обновление экрана и вычисления для ускорения
With Application
.Calculation = xlCalculationManual
.ScreenUpdating = False
.EnableEvents = False
.DisplayAlerts = False
End With
' Указываем лист для копирования
Set srcWs = ThisWorkbook.Sheets("Board")
' Открываем книгу назначения
Set dstWb = Workbooks.Open("C:\Users\xxx\Desktop\Workbook2.xlsb")
srcWs.Copy Before:=dstWb.Sheets(1)
Set dstWs = dstWb.Sheets(1)
srcWbName = ThisWorkbook.Name
dstWbName = dstWb.Name
' Обновление ссылок на макросы для ActiveX и фигур
UpdateActiveXControls dstWs, srcWbName, dstWbName
UpdateShapes dstWs, srcWbName, dstWbName
UpdateCharts dstWs, srcWbName, dstWbName
' Завершение работы
With Application
.Calculation = xlCalculationAutomatic
.ScreenUpdating = True
.EnableEvents = True
.DisplayAlerts = True
End With
End Sub
Sub UpdateActiveXControls(ws As Worksheet, srcWbName As String, dstWbName As String)
Dim ctl As Object
For Each ctl In ws.OLEObjects
If InStr(1, ctl.Object.OnAction, srcWbName, vbTextCompare) > 0 Then
ctl.Object.OnAction = Replace(ctl.Object.OnAction, srcWbName, dstWbName)
End If
Next ctl
End Sub
Sub UpdateShapes(ws As Worksheet, srcWbName As String, dstWbName As String)
Dim shp As Shape
For Each shp In ws.Shapes
If shp.OnAction <> "" Then
If InStr(1, shp.OnAction, srcWbName, vbTextCompare) > 0 Then
shp.OnAction = Replace(shp.OnAction, srcWbName, dstWbName)
End If
End If
' Проверка и обновление формул
If shp.Type = msoAutoShape Or shp.Type = msoShape Then
If InStr(1, shp.Formula, srcWbName, vbTextCompare) > 0 Then
shp.Formula = Replace(shp.Formula, srcWbName & "!", dstWbName & "!")
End If
End If
Next shp
End Sub
Sub UpdateCharts(ws As Worksheet, srcWbName As String, dstWbName As String)
Dim chartObj As ChartObject
Dim srs As Series
For Each chartObj In ws.ChartObjects
For Each srs In chartObj.Chart.SeriesCollection
If InStr(1, srs.Formula, srcWbName, vbTextCompare) > 0 Then
srs.Formula = Replace(srs.Formula, srcWbName & "!", dstWbName & "!")
End If
Next srs
Next chartObj
End Sub
Подробности реализации
-
Копирование листа: Мы используем
srcWs.Copy
для создания копии листа и помещаем его перед первым листом в целевой книге. -
Обновление ActiveX управляемых элементов: Метод
UpdateActiveXControls
проходит по всем элементам управления ActiveX на листе и обновляет их свойстваOnAction
, чтобы они указывали на соответствующую книгу. -
Обновление фигур: Метод
UpdateShapes
проверяет каждую фигуру на наличие свойствOnAction
иFormula
. Убедитесь, что двойная проверка происходит для типовmsoAutoShape
иmsoShape
, поскольку для некоторых фигур, как округлые прямоугольники и октогоны, ваша ошибка могла быть связана с неправильным обращением к свойствуFormula
. -
Обновление диаграмм: Метод
UpdateCharts
берет каждую диаграмму на листе и проходит по ее коллекции серий, обновляя формулы.
Заключение
Правильное управление ссылками и обновление их после копирования листа обеспечит корректную работу всех элементов управления и диаграмм в новой книге. Правильно организованный код также улучшит читаемость и управление. Убедитесь, что ваши пути и имена файлы соответствуют действительности, чтобы избежать ошибок при выполнении.