Как сохранить код VBA при копировании листа с помощью openpyxl?

1

У меня есть рабочий лист с кодом VBA (в Excel, щелкните правой кнопкой мыши имя листа и код просмотра), который я хотел бы скопировать в той же книге.

При использовании workbook.copy_worksheet() код VBA, содержащийся на листе, теряется.

Я посмотрел на свойство worksheet.vba_code но, похоже, он содержит только некоторые свойства листов, а не код VBA.

Теги:
excel
openpyxl

2 ответа

1
Лучший ответ

Я думаю, проблема в том, что сами рабочие листы не содержат кода VBA. Это хранится в виде блоба в пакете XLSX и может содержать жестко закодированные ссылки на конкретные рабочие листы. К сожалению, капли VBA не покрываются спецификацией OOXML, поэтому нет способа узнать. Вы могли бы быть хорошо, если вы копируете свойство vba_code вручную, но нет никакой гарантии, и это так же, как вероятность того, что Excel будет жаловаться на файл.

  • 0
    Ну, вот чего я боялся ... Я уже пытался скопировать свойство вручную, но оно не сработало.
  • 0
    Существуют и другие зависимости для таких вещей, как элементы управления. Их поддержка в openpyxl ограничена воссозданием структуры архива исходного файла, поэтому большинство изменений сломают это. Некоторое из этого может быть улучшено, но я подозреваю, что не то, что вам нужно. Это также, почему copy_worksheet ограничен в области.
0

Обходной путь, который я нашел, заключался в том, чтобы добавить код VBA к самой книге, которая копирует код VBA из листа друг с другом.

Я добавил это в код книги VBA:

Private Sub Workbook_Open()

    Dim CodeCopy As Object
    Dim CodePaste As Object
    Dim numLines As Integer
    Dim sheetNumber As Integer

    Set CodeCopy = ActiveWorkbook.VBProject.VBComponents(Worksheets(1).CodeName).CodeModule

    For sheetNumber = 2 To Worksheets.Count
        Set CodePaste = ActiveWorkbook.VBProject.VBComponents(Worksheets(sheetNumber).CodeName).CodeModule
        numLines = CodeCopy.CountOfLines

        If CodePaste.CountOfLines > 1 Then
            CodePaste.DeleteLines 1, CodePaste.CountOfLines
        End If

        CodePaste.AddFromString CodeCopy.Lines(1, numLines)
    Next
End Sub

Решение основано на этом и этом.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню