Как встроить кнопку в новы документ
К примеру мне надо добавить в событие кнопки Click - BEEP ?
Спасибо.
Мне необходимо встроить в новый документ кнопку, но не просто кнопку, а уже с определенным кодом. Как это можно сделать.
К примеру мне надо добавить в событие кнопки Click - BEEP ?
Спасибо.
Ты имеешь ввиду - чтобы при работе макроса создавался программно документ с уже написанным макросом? Если да, то я не умею. Боюсь, что и никто не умеет. ВБА командует только над Экселем (Вордом, Аксессом), но не над ВБА.
Ты имеешь ввиду - чтобы при работе макроса создавался программно документ с уже написанным макросом? Если да, то я не умею. Боюсь, что и никто не умеет. ВБА командует только над Экселем (Вордом, Аксессом), но не над ВБА.
Жаль, тогда наверно придется сделать заготовок и в него копировать. Но все равно спасибо
А вот как-то на форуме посвященном Access видел такой кусок кода (сам еще не пробовал его):
Dim XLS As Object
Dim M As Object
Set XLS = CreateObject("Excel.Application")
XLS.Visible = True
XLS.Workbooks.Add
Set M = XLS.ActiveWorkbook.VBProject.VBComponents.Add(1)
DoCmd.OpenModule "Macros"
M.CodeModule.AddFromString Application.Modules("Macros").Lines(1 + 1, Application.Modules("Macros").CountOfLines - 2)
End Sub
Вот эти строчки:
DoCmd.OpenModule "Macros";
Application.Modules("Macros").Lines
- относятся к Access (просто товарищ предложил хранить код в модуле Access, через OLE создать новую книгу Excel, в модуль этой книги включить код и запустить - типа код внутри Excela работает быстрее, чем через OLE), а ты можешь хранить код в переменных, текстовом файле, ну или также своем модуле
Теперь на счет библиотеки, по моим скоротечным наблюдениям для этого кода надо указать - Microsoft VBScript Globals и после написания строчки .ActiveWorkbook.VBProject.VBComponents.Add(vbext_ct_StdModule - она мне ляпнула, что ей надо еще одну библиотеку подключить, которой оказалась - Microsoft Visual Basic for Applications Extensibility 5.3
- так, ну это все что я знаю, так что дерзай, пиши и пиши сюда, что получится ;)
Мне необходимо встроить в новый документ кнопку, но не просто кнопку, а уже с определенным кодом. Как это можно сделать.
К примеру мне надо добавить в событие кнопки Click - BEEP ?
Спасибо.
Вот работающий пример. Надо создать CommandButton и записать на нее этот код. Должна открыться новая книга, в ней создается CommandButton с приветствием.
Private Sub CommandButton1_Click()
Workbooks.Add
ActiveSheet.OLEObjects.Add(ClassType:="Forms.CommandButton.1", Link:=False _
, DisplayAsIcon:=False, Left:=164.25, Top:=27, Width:=45, Height:= _
41.25).Select
n = Application.VBE.VBProjects.Count
Application.VBE.ActiveVBProject.VBComponents(2).CodeModule.InsertLines 1, "Private Sub CommandButton1_Click()"
Application.VBE.ActiveVBProject.VBComponents(2).CodeModule.InsertLines 2, "MsgBox ""Hello from new book!"""
Application.VBE.ActiveVBProject.VBComponents(2).CodeModule.InsertLines 3, "End Sub"
End Sub
Вот работающий пример. Надо создать CommandButton и записать на нее этот код. Должна открыться новая книга, в ней создается CommandButton с приветствием.
Private Sub CommandButton1_Click()
Workbooks.Add
ActiveSheet.OLEObjects.Add(ClassType:="Forms.CommandButton.1", Link:=False _
, DisplayAsIcon:=False, Left:=164.25, Top:=27, Width:=45, Height:= _
41.25).Select
n = Application.VBE.VBProjects.Count
Application.VBE.ActiveVBProject.VBComponents(2).CodeModule.InsertLines 1, "Private Sub CommandButton1_Click()"
Application.VBE.ActiveVBProject.VBComponents(2).CodeModule.InsertLines 2, "MsgBox ""Hello from new book!"""
Application.VBE.ActiveVBProject.VBComponents(2).CodeModule.InsertLines 3, "End Sub"
End Sub
А в 97-м такой штуки нет! Понятно, почему я об этом не знаю...
На исходник ВБА я поставил пароль, и данные не переносятся. То есть, если я зайду в ВБА и введу пароль, то данные переносятся в кнопку нового документа, (то что я создаю), а если я не введу пароль, то документ и кнопка создается, а данные в кнопку не переносятся.
Что делать?
Теперь другая проблема:
На исходник ВБА я поставил пароль, и данные не переносятся. То есть, если я зайду в ВБА и введу пароль, то данные переносятся в кнопку нового документа, (то что я создаю), а если я не введу пароль, то документ и кнопка создается, а данные в кнопку не переносятся.
Что делать?
Недавно открыл подобную тему, но ответа так и не получил:(
:-? А можно открыть редактор VBA (програмно, через VB например), затем открыть нужный проект (по идее должно появиться окошко "Enter password"), определить его и ввести пароль...
...надо попробовать...:!!!:
Теперь другая проблема:
На исходник ВБА я поставил пароль, и данные не переносятся. То есть, если я зайду в ВБА и введу пароль, то данные переносятся в кнопку нового документа, (то что я создаю), а если я не введу пароль, то документ и кнопка создается, а данные в кнопку не переносятся.
Что делать?
Если я правильно понял, ты поставил пароль на просмотр проекта?
У меня все работает и в этом случае - и кнопка в новой книге создается и код переписывается.
Перешли свой пример - подумаем.
Если я правильно понял, ты поставил пароль на просмотр проекта?
У меня все работает и в этом случае - и кнопка в новой книге создается и код переписывается.
Перешли свой пример - подумаем.
Вота!
Тупо, но работает...
Declare Function GetUserName Lib "advapi32.dll" Alias "GetUserNameA" (ByVal lpBuffer As String, nSize As Long) As Long
Public Declare Function GetFocus Lib "user32" () As Long
Sub Main()
Dim XL As Object
Dim UserProphile As String
Dim MyWB As Object
Dim VBAHWND
Dim username As String
Dim slength As Long
Dim retval As Long
username = Space(255)
slength = 255
retval = GetUserName(username, slength)
username = Left(username, slength - 1)
'Обрати внимание на путь...
UserProphile = "C:\Documents and Settings\" & username & "\Application Data\Microsoft\Excel\XLSTART\"
Set XL = CreateObject("Excel.Application")
XL.Visible = True
With XL
Set MyWB = .workbooks.open(FileName:=UserProphile & "PERSONAL.XLS")
End With
SendKeys ("%{F11}"), True
Call GetFocus
SendKeys ("^{r}"), True
SendKeys "{Enter}", True
'Здеся по буквам пиши свой пароль...
SendKeys "{p}", True
SendKeys "{a}", True
SendKeys "{s}", True
SendKeys "{s}", True
SendKeys "{w}", True
SendKeys "{o}", True
SendKeys "{r}", True
SendKeys "{d}", True
SendKeys "{Enter}", True
End Sub
...это я погорячился:)
Если я правильно понял, ты поставил пароль на просмотр проекта?
У меня все работает и в этом случае - и кнопка в новой книге создается и код переписывается.
Перешли свой пример - подумаем.
Пароль на открытие goliaph
Пароль на листы zaq
пароль на ВБ 12297
Пароль на открытие goliaph
Пароль на листы zaq
пароль на ВБ 12297
У меня zip не открывается. То ли поломан, то ли больно новый формат. Может пошлешь самораспаковывающий?
У меня zip не открывается. То ли поломан, то ли больно новый формат. Может пошлешь самораспаковывающий?
Твой пример со второго раза распаковался.
После небольшой доделки он нормально прошел.
Я был немного не прав (мало опыта переноса кода) с Application.VBE.ActiveVBProject.VBComponents(2)
Я думал, что 2-й компонент это всегда "Лист1", а он в твоем случае писал на "ЭтаКнига".
Дабы этого избежать надо определить нужный компонент, например
For Each c In Application.VBE.ActiveVBProject.VBComponents
If c.Name = "Лист1" Then Exit For
Next c
и потом обращаться
c.CodeModule.InsertLines 1, "Private Sub..."
После такой доработки твоя симпатичная программа спрашивала пароль только в начале -GOLIAPH-. Потом все работало и кнопка на прайс листе обрабатывала заказы. Правда первый раз я ее нажал не введя в графе заказы ничего и программа зависла. Наверное следует сделать "защиту от дурака" (от меня ;) ).
И еще. Первый лист в создаваемой книги может не всегда называться "Лист1" в английском Офиссе - Sheet1, а на другой мове еще как-то. Тебе следует возможно это предусмотреть.
.
.
.
.
.
И еще. Первый лист в создаваемой книги может не всегда называться "Лист1" в английском Офиссе - Sheet1, а на другой мове еще как-то. Тебе следует возможно это предусмотреть.
Я беру именно номер страницы (1), думаю так сработает.
З.Ы. Как вам "альфа" версия документа, покатит?
Я беру именно номер страницы (1), думаю так сработает.
З.Ы. Как вам "альфа" версия документа, покатит?
Имеешь ввиду вместо "Лист1" использовать
Sheets(1).name. Да так и надо. Как-то сразу не дотумкал.
Версия мне нравится, правда я по другому ведомству. :)
Имеешь ввиду вместо "Лист1" использовать
Sheets(1).name. Да так и надо. Как-то сразу не дотумкал.
Версия мне нравится, правда я по другому ведомству. :)
Теперь напрашивается парочка других вопросов:
1-Что если открыто много екселевских документов?
2-Как изменить Caption кнопки.
3-Как встроить пару кнопок и их различать.
Теперь напрашивается парочка других вопросов:
1-Что если открыто много екселевских документов?
2-Как изменить Caption кнопки.
3-Как встроить пару кнопок и их различать.
Вопрос 2. Ответ.
Надо перед Caption ставить Object
Selection.Object.Caption = "Заказ1"
Вопрос 3. Ответ.
Пробовал ставить вторую кнопку - вылетает Эксель. Буду разбираться.
Вопрос 2. Ответ.
Надо перед Caption ставить Object
Selection.Object.Caption = "Заказ1"
Вопрос 3. Ответ.
Пробовал ставить вторую кнопку - вылетает Эксель. Буду разбираться.
Мой прогноз ответа на Вопрос 3: после добавления 1-й кнопки фокус оказывается у нее. Поэтому большая часть операций с переменной ActiveSheet невыполнима. Попробуйте перед добавлением кнопки сделать ActiveCell.Activate
Это очень полезная штука.
ActiveCell.Activate - мммммм, возьму на заметку :)
Если в файле есть хоть один встроенный объект - любой макрос надо начинать с этого. Дело в том, что у кнопки можно свойство TakeFocusOnClick сделать False. Но если перед кнопкой юзер скажем, менял какой-нибудь CheckBox - фокус тогда останется у CheckBox-a - и привет, приплыли. Но не факт, что конкретно в вышеизложенном случае именно в этом ошибка - это просто мое предположение.
Мой прогноз ответа на Вопрос 3: после добавления 1-й кнопки фокус оказывается у нее. Поэтому большая часть операций с переменной ActiveSheet невыполнима. Попробуйте перед добавлением кнопки сделать ActiveCell.Activate
Это очень полезная штука.
Увы. И с полезной штукой вылетает.
Вот код для начальной кнопки.
Private Sub CommandButton1_Click()
Workbooks.Add
'-------------------- add 1st button
ActiveSheet.OLEObjects.Add(ClassType:="Forms.CommandButton.1", Link:=False _
, DisplayAsIcon:=False, Left:=164.25, Top:=27, Width:=45, Height:= _
41.25).Select
Selection.Object.Caption = "Zakaz1"
For Each c In Application.VBE.ActiveVBProject.VBComponents
If c.Name = Sheets(1).Name Then Exit For
Next c
c.CodeModule.InsertLines 1, "Private Sub CommandButton1_Click()"
c.CodeModule.InsertLines 2, "MsgBox ""Zakaz 1"""
c.CodeModule.InsertLines 3, "End Sub"
'-------------------- add 2nd button
ActiveCell.Activate
ActiveSheet.OLEObjects.Add(ClassType:="Forms.CommandButton.2", Link:=False _
, DisplayAsIcon:=False, Left:=164.25, Top:=127, Width:=45, Height:= _
41.25).Select
Selection.Object.Caption = "Zakaz2"
c.CodeModule.InsertLines 4, "Private Sub CommandButton2_Click()"
c.CodeModule.InsertLines 5, "MsgBox ""Zakaz 2"""
c.CodeModule.InsertLines 6, "End Sub"
End Sub
Имеешь ввиду вместо "Лист1" использовать
Sheets(1).name. Да так и надо. Как-то сразу не дотумкал.
Версия мне нравится, правда я по другому ведомству. :)
Нет, так не пойдет ( Sheets(1) ), при таком раскладе оно дописывает в текущий документ, получается два одинаковых события.
Я сделаю по другому, в начале присвою какое-то особое имя, к примеру 1224400ваыв23, и по нему буду искать нужный лист, а потом поменяю на что-то нормальное.
Нет, так не пойдет ( Sheets(1) ), при таком раскладе оно дописывает в текущий документ, получается два одинаковых события.
Я сделаю по другому, в начале присвою какое-то особое имя, к примеру 1224400ваыв23, и по нему буду искать нужный лист, а потом поменяю на что-то нормальное.
Попробуйте обращаться к нужному листу через CommandButton:
ActiveSheet.OLEObjects.Add(ClassType:="Forms.CommandButton.1", Link:=False _
, DisplayAsIcon:=False, Left:=164.25, Top:=27, _ Width:=45, Height:=41.25).Select
'Здесь присваиваем переменной кнопку.
Set CB = Selection.Object
CB.Caption = "Caption"
'Специально выбираем другой лист.
Sheets(3).Select
'Активируем кнопку.
CB.Activate
'Имя листа соответствует листу с кнопкой!
nAm = ActiveSheet.Name
For Each c In Application.VBE.ActiveVBProject.VBComponents
If c.Name = nAm Then Exit For
Next c
With c
.CodeModule.InsertLines 2, "Private Sub " & CB.Name & "_Click()"
.CodeModule.InsertLines 3, "MsgBox ""Zakaz 1"""
.CodeModule.InsertLines 4, "end sub"
End With
...у меня вроде работает:)
Нет, так не пойдет ( Sheets(1) ), при таком раскладе оно дописывает в текущий документ, получается два одинаковых события.
Я сделаю по другому, в начале присвою какое-то особое имя, к примеру 1224400ваыв23, и по нему буду искать нужный лист, а потом поменяю на что-то нормальное.
Гланды можно вырезать конечно по-всякому.
Если кнопку надо вставлять не в активную книгу - пиши в какую. Вместо 'особого имени' листа проще запомнить или задать имя книги после ее создания
Workbooks.Add
wb1 = ActiveWorkbook.Name
а потом прямо обращаться в лоб
wb1.Sheets(1).Name
Гланды можно вырезать конечно по-всякому.
Если кнопку надо вставлять не в активную книгу - пиши в какую. Вместо 'особого имени' листа проще запомнить или задать имя книги после ее создания
Workbooks.Add
wb1 = ActiveWorkbook.Name
а потом прямо обращаться в лоб
wb1.Sheets(1).Name
Если верно:
Workbooks.Add
wb1 = ActiveWorkbook.Name,
то не
wb1.Sheets(1).Name,
а
Workbooks(wb1).Sheets(1).Name
А еще лучше:
Set wb1=Workbooks.Add
и тогда верно:
wb1.Sheets(1).Name
1. Если хочешь создавать кнопочку с одинаковыми действиями для любого листа - проще создать панельку инструментов с кнопочкой и написать код для обработки её событий. В качестве одного из аргументов будет выступать акт.лист .
2. При добавлении динамически добавляемого кода в программу лучше не защищать проект, а запретить доступ к открытию VBA IDE и потом спокойно работать.
Удачи....