Как экспортировать кнопки и детали листа с помощью VBA

Я возился с импортом/экспортом модулей и классов VBA в приложении Excel, над которым я работаю. Кажется действительно полезным для использования с контролем версий. Мне это нравится. Я могу легко вносить изменения кода в модули, экспортировать свои изменения, фиксировать и отправлять свои изменения, а также «перезагружать» (удалять все модули и повторно импортировать) свои изменения в другом экземпляре приложения Excel.

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

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

Любые предложения или решения этой проблемы?

РЕДАКТИРОВАТЬ: Чтобы было ясно, я знаю, что могу экспортировать свои листы как модули. Однако, кажется, нет ничего, что указывало бы на то, как лист выглядел при экспорте. Следовательно, когда я импортирую «лист», он импортируется как модуль класса.


person aCarella    schedule 21.12.2016    source источник
comment
Вчера я ответил на аналогичный вопрос код vba"> stackoverflow.com/questions/41240745/   -  person S Meaden    schedule 21.12.2016


Ответы (2)


«Лист» — это тип Document VBComponent, который является модулем класса, подклассом определенного типа объекта в объектной модели основного приложения (здесь — класс Worksheet). Таким образом, часть «кода» экспортируется как модуль класса; часть «документ» — это ваш основной документ — это содержимое намного больше, чем просто значения ячеек и формулы (шрифты, форматы ячеек, условные форматы, комментарии к ячейкам, формы и т. д.), и в Office 2007+ они сериализованы в формате XML, упакованы в .zip (который затем переименовывается с расширением .xlsx): для надлежащего контроля исходного кода документа вам нужны различия собственно XML.

Кроме того, вы не можете импортировать тип документа VBComponent обратно в VBProject, потому что это основное приложение, которому принадлежат компоненты типа документа. Например, чтобы добавить рабочий лист в ThisWorkbook, вам нужно использовать объектную модель Excel и вызвать ThisWorkbook.Worksheets.Add; то же самое для их удаления.

Вот почему не существует решения для управления исходным кодом для VBA, которое имело бы дело с каждым отдельным вариантом использования: чтобы оно было полнофункциональным, оно должно было бы иметь возможность изменять сжатый XML самой структуры документа, в то время как этот документ открыть, загрузив XML с диска.

У меня есть этот проект OSS, Rubberduck, в котором есть встроенный контроль версий Git:

Панель управления версиями Rubberduck

Он не зависит от хоста, поэтому в том, что он делает, нет ничего специфичного для хоста, но даже если какой-то утверждать, что "это просто", на самом деле это не так: один человек будет доволен возможностью восстановить код программной части; другому нужны значения ячеек и формулы; другой должен иметь возможность восстанавливать фигуры, их форматы и назначенные макросы, а другой человек будет жаловаться, потому что они теряют свои условные форматы при восстановлении своего проекта из системы управления версиями: в конце концов, единственный способ иметь тип документа VBComponent под управлением исходного кода, состоит в том, чтобы извлечь его XML и сохранить это под контролем исходного кода... но тогда вы не сможете полностью восстановить документ.

Единственное разумное решение - максимально отделить реализацию кода VBA от документа - написать код VBA, который работает независимо от того, какие рабочие листы находятся в рабочей книге, в которой размещен код; параметризовать все и иметь модуль, который генерирует макеты и форматы рабочих листов и еще много чего - другими словами, не «проектируйте» рабочие листы (в Excel), не «кодируйте» их (в VBE).

Что касается данных... ну, не повезло: система контроля версий предназначена для кода, а не для данных.

person Mathieu Guindon    schedule 21.12.2016
comment
Я согласен с последней фразой в предпоследнем абзаце, напишите код для рисования на листе, а затем вы можете сравнить этот код, чтобы увидеть, как изменился лист. - person S Meaden; 22.12.2016
comment
Да. Определенно нужен контроль версий для пользовательского интерфейса/листов, а не данных, которые на них живут. Например, я мог бы написать код, который создает пользовательский интерфейс, о чем вы упомянули. Я мог бы сделать именно это, чтобы затем внедрить этот код в остальную часть системы контроля версий проекта. Очень полезный ответ. - person aCarella; 22.12.2016

Вчера я ответил на аналогичный вопрос Система управления версиями для Excel-VBA код

Листы управления исходным кодом сложны. Представьте, что вы сериализуете данные в ячейках A1, A2, A3, поэтому у вас может быть

A1:"Foo"
A2:"Bar"
A3:"Baz"
...
A5577: "Kevin"

т. е. много строк. затем вы вставляете строку в строку вверху, например, 3, тогда все строки ниже будут рассинхронизированы и выдадут 5000! несоответствия в сравнении версий; это очень раздражало (когда я работал над системой, которая делала это).

Возможно, вы захотите хорошо подумать об этой проблеме и опубликовать возможное решение. Быстро подумав об этом, я задаюсь вопросом, поможет ли какая-то логика, аналогичная связанному списку. Итак, один сериализует ячейку, а затем также сериализует ссылку на следующую ячейку, а другой проходит весь список ячеек. Тогда для вставки одной строки потребуется только одно изменение — вставка ссылки.

person S Meaden    schedule 21.12.2016
comment
FWIW Я не думаю, что есть решение этой проблемы. Это всего лишь неприятный побочный эффект внедрения VBA в основной документ, и в этом его природа. - person Mathieu Guindon; 22.12.2016