Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Excel VBA (часть 3)

Автор: AndVGri
Дата сообщения: 18.11.2010 02:21
faust2k

Цитата:
Что за ошибка "Argument not optional", возникающая при возврате значения из функции? Где, что нужно поправлять?

Буквально "аргумент не является опцией". То есть в функции пропущен один из обязательных аргументов. Смотрите описание по функции
Автор: faust2k
Дата сообщения: 18.11.2010 09:26
Получает функция аргумент нормально. Потом я ей присваиваю значение, например 1, и на возврате получается такая ошибка. Правильно я понимаю, что название функции при возврате превращается в переменную?

Public Function myfunc(ByRef Str As String) As Integer
.Cells(2, 1).Value = Str
myfunc = 1
End Function

myfunc 2 ' отправляю в функцию двойку
.Cells(1, 1).Value = myfunc 'возвращаю единичку
Автор: AndVGri
Дата сообщения: 18.11.2010 09:56
faust2k

Цитата:
.Cells(1, 1).Value = myfunc 'возвращаю единичку

вот, вот здесь и не передаёте функции аргумент
правильно

Код:
.Cells(1, 1).Value = myfunc(2)
'или
Dim myfuncResult As Integer
myfuncResult = myfunc(2)
.Cell(1, 1).Value = myfuncResult
Автор: Alexikit
Дата сообщения: 18.11.2010 14:52
подскажите пожалуйста, строю график пишу код


Код:
Set wgr1 = Application.ActiveWorkbook.ActiveSheet
wgr1.ChartObjects.Add 100, 30, 400, 250
Set gr1 = wgr1.ChartObjects(1).Chart

gr1.ChartType = xlXYScatterSmooth

With gr1
.HasTitle = True
.ChartTitle.Text = "толщина"
End With
Автор: KF121
Дата сообщения: 18.11.2010 14:56
не обходимо активировать ваш чарт. и после этог уже дулать ActiveChart.HasTitle и ActiveChart.ChartTitle.Text

сам объект не имеет таких полей, а вот выделенный обладает. ООП такое у них %)
Автор: Alexikit
Дата сообщения: 18.11.2010 15:08
спасибо, но что-то с активированием у меня проблемы
просто код
gr1. Activate
не работает


Добавлено:
в итоге написала такой код


Код:
Set wgr1 = Application.ActiveWorkbook.ActiveSheet
wgr1.ChartObjects.Add 100, 30, 400, 250

ActiveSheet.ChartObjects(1).Activate
Set gr1 = wgr1.ChartObjects(1).Chart
gr1.ChartType = xlXYScatterSmooth
With ActiveChart
.HasTitle = True
.ChartTitle.Text = "толщина"
End With
Автор: KF121
Дата сообщения: 18.11.2010 15:32
Чтобы показывалось имя, нужно сначала добавить данные в чарт. Следующий код показывает это все.

Не обходимо забить ячейки A1 - A11

Sub ss()
Dim gr1 As Chart
Dim wgr1 As Worksheet

Set wgr1 = Application.ActiveWorkbook.ActiveSheet
wgr1.ChartObjects.Add 100, 30, 400, 250
Set gr1 = wgr1.ChartObjects(1).Chart

With wgr1.ChartObjects(1)
.Activate
With ActiveChart.SeriesCollection.NewSeries
.Name = "DATA"
.Values = ActiveSheet.Range("A1:A11").Value
.XValues = ActiveSheet.Range("A1:A11").Value
.ChartType = xlLine
End With ' New series
End With ' New series

With gr1
.HasTitle = True
.ChartTitle.Text = "òîëùèíà"
End With
End Sub
Автор: Alexikit
Дата сообщения: 18.11.2010 15:46
спасибо, построилось, но у меня будет строится 4 графика, причем в цикле, а потом я должна присвоитть им названия, что-то я не пойму как их по очереди активировать, причем в конце. Тоесть активировать мне надо не там где я строю данные на графике, там идет цикл и в однос цикле будут строиться несколько графиков.
Автор: KF121
Дата сообщения: 18.11.2010 16:00
Я думаю что в данном случае активация не нужна. т.к. данные уже будут присутсвовать
так в цикле и выполнять

for inCnt = 1 to 4
With wgr1.ChartObjects(inCnt).Chart
.HasTitle = True
.ChartTitle.Text = "bla-bla"
End With
NExt
Автор: Alexikit
Дата сообщения: 19.11.2010 11:42
KF121
Спасибо за советы, действительно если данные присутствуют активация не нужна, заголовок добавляется.

Но теперь не удается построить одновременно два графика, программа затирает данные первого и записывает втрой туда же, хотя вроде объекты разные, код сейчас выглятит так


Код:
Set wgr1 = Application.ActiveWorkbook.ActiveSheet
wgr1.ChartObjects.Add 100, 30, 400, 250

Set gr1 = wgr1.ChartObjects(1).Chart
gr1.ChartType = xlXYScatterSmooth

For i = 1 To jj
gr1.SeriesCollection.NewSeries
gr1.SeriesCollection(yjgr1(i) - 1).XValues = ActiveSheet.Range(ActiveSheet.Cells(xj1(i), 1), ActiveSheet.Cells(xj2(i), 1))
gr1.SeriesCollection(yjgr1(i) - 1).Values = ActiveSheet.Range(ActiveSheet.Cells(xj1(i), 3), ActiveSheet.Cells(xj2(i), 3))
gr1.SeriesCollection(yjgr1(i) - 1).Name = "=""Chart11 """
Next
With gr1
.HasTitle = True
.ChartTitle.Text = "толщина"
End With

Set wgr2 = Application.ActiveWorkbook.ActiveSheet
wgr2.ChartObjects.Add 100, 30, 400, 250

Set gr2 = wgr2.ChartObjects(1).Chart
gr2.ChartType = xlXYScatterSmooth
For i = 1 To jj
gr2.SeriesCollection.NewSeries
gr2.SeriesCollection(yjgr1(i) - 1).XValues = ActiveSheet.Range(ActiveSheet.Cells(xj1(i), 1), ActiveSheet.Cells(xj2(i), 1))
gr2.SeriesCollection(yjgr1(i) - 1).Values = ActiveSheet.Range(ActiveSheet.Cells(xj1(i), 4), ActiveSheet.Cells(xj2(i), 4))
gr2.SeriesCollection(yjgr1(i) - 1).Name = "=""Chart11 """
Next
With gr2
.HasTitle = True
.ChartTitle.Text = "толщина%"
End With
Автор: KF121
Дата сообщения: 19.11.2010 11:45
Данные затираются из-за того что у вас gr2 сслыется на первый чарт "Set gr2 = wgr2.ChartObjects(1).Chart"
а еще было бы не плохо этим чартам давать координаты, иначе они накладываются друг на друга.
Автор: Alexikit
Дата сообщения: 19.11.2010 11:51
KF121
Класно, спасибо, все пошло.
Автор: Frantishek
Дата сообщения: 22.11.2010 06:43
Прошу подсказать, как возможно оптимизировать запуск Эксель (как понимаю, без средств VBA здесь не обойтись), если приходится работать с ним многократно закрывая и открывая документы (и саму программу).
Одним словом, как добиться той скорости запуска, что характерна для легковесных приложений, определивших их популярность, в том числе из-за этого качества, вроде - Media Player Classic, uTorrent и т.д. Спасибо.
Автор: mcdie
Дата сообщения: 23.11.2010 08:17
Frantishek
Не совсем по теме, но кое что есть:
[more]
Ускорение запуска табличного редактора

Запуск практически любой программы не обходится без демонстрации заставки. Однако вывод ее на экран, безусловно, требует от системы некоторых ресурсов и времени, а значит, снижает скорость загрузки приложения.
Чтобы оптимизировать запуск Microsoft Excel, необходимо модифицировать параметры загрузки программы, изменив командную строку в ярлыке данного приложения. Найдите папку, в которой установлен пакет Microsoft Office (например, C:\Program Files\Microsoft Office\OFFICE11), и создайте ярлык для Excel. Для этого щелкните по этой программе правой кнопкой мыши и в контекстном меню укажите «Отправить | Рабочий стол (создать ярлык)». Затем найдите этот ярлык на Рабочем столе, снова кликните правой кнопкой и выберите «Свойства». В появившемся окне в закладке «Ярлык» найдите строку ввода напротив поля «Объект». Добавьте в конце строки «/E», чтобы в результате она приняла приблизительно следующий вид: «C:\Program Files\Microsoft Office\OFFICE11\EXCEL.EXE» /E». Сохраните изменения. Теперь, дважды кликнув по этому ярлыку, вы запустите Excel без стартовой картинки, и этот процесс станет значительно быстрее. Кроме того, вы можете ускорить старт программы, задав для ее запуска комбинацию клавиш. Для этого в том же окне свойств ярлыка установите курсор в поле «Быстрый вызов» и нажмите требуемое сочетание на клавиатуре.
[/more]
Автор: ZlydenGL
Дата сообщения: 23.11.2010 09:52
Frantishek, на самом деле VBA тут ни при чем совершенно. VBA - это лишь инструмент разработчика, он не имеет совершенно никакого влияния на текущие процедуры загрузки Ёкселя. Можно конечно прописать глобальный хук на приложение, которое в случае закрытия приложения будет его не закрывать, а прятать (скрывать), но это ИМХО может привести к тому, что в один "прекрасный" момент память окажется загаженной кучей процессов excel.exe.

Поэтому если так требуется ускорить именно запуск - имеет смысл пойти рутинной тропой: "подкрутить" prefetch механизм винды, отключить неиспользуемые аддоны, оптимизировать систему в целом (например когда в последний раз запускался процесс дефрагментации на винте?) и так далее.
Автор: Frantishek
Дата сообщения: 23.11.2010 10:04
ZlydenGL
а если кастомизировать интерфейс? убрать все ненужное, что то может дать?

Добавлено:
mcdie
пробовал такое делать на портабл версии, помимо заставки почему то не грузятся и начальные таблицы (листы), при этом сам процесс старта выглядит болезненным и не дает ожидаемого прироста в скорости
Автор: ZlydenGL
Дата сообщения: 23.11.2010 10:08
Frantishek, а что понимается под кастомизацией? Я лично понимаю только пресловутое отключение лишний аддонов, что на современном железе ИМХО значительного эффекта не даст.

И все-таки, когда на Вашей машине в последний раз запускалась дефрагментация?

Добавлено:
С заставкой париться вообще смысла нет ИМХО. Во времена процессоров на Socket 7 заставки и прочая действительно могли "кушать" много ресурсов, но даже на 3х пнях отключение интерфейсной части загрузки ИМХО уже никак не сказывалось на самой загрузке.
Автор: mcdie
Дата сообщения: 23.11.2010 12:43
Никак не могу найти в Excel VBA функцию которая выдаёт истину если файл существует и ложь если отсутсвует.
Автор: ZlydenGL
Дата сообщения: 23.11.2010 12:44
mcdie, Dir()?

Добавлено:
Только она возвращает имя файла если он есть и пустую строку если его нет. Т.е. проверка будет выглядеть так:


Код: Dim FName As String

FName = "c:\autoexec.bat"
If Dir(FName) = "" Then
' Такого файла в указанной директории нет
Else
' Файл есть
End If
Автор: KF121
Дата сообщения: 23.11.2010 12:48
FileExists у объкта файловой системы
Автор: febreze2009
Дата сообщения: 24.11.2010 10:45
Всем привет!

В Excel создана таблица для печати на формат А4. В углу есть поле со сквозной нумерацией.
Нужно чтобы при печати каждый последующий лист печатался с номером N+1, следующий N+2 и т.д. N - можно задать, чтобы не печатать такие листы, которые печатались в прошлый раз.

Как можно лучше реализовать данную задачу?
Автор: smirnvlad
Дата сообщения: 24.11.2010 13:24
febreze2009
по событию Workbook_BeforePrint определять максимальный номер, и проставлять номера на листы где номер не заполнен
что-то вроде
[more]
Код: [no]
Private Sub Workbook_BeforePrint(Cancel As Boolean)

ListNumCell = "A1"

MaxNum = 0

For i = 1 To Sheets.Count
If Range(ListNumCell).Value > MaxNum Then MaxNum = Range(ListNumCell).Value
Next

For i = 1 To Sheets.Count
If IsEmpty(Sheets(i).Range(ListNumCell).Value) Then
MaxNum = MaxNum + 1
Sheets(i).Range(ListNumCell).Value = MaxNum
End If
Next

End Sub

[/no]
Автор: febreze2009
Дата сообщения: 24.11.2010 16:08

Цитата:

по событию Workbook_BeforePrint определять максимальный номер, и проставлять номера на листы где номер не заполнен
что-то вроде


Не совсем понял. Можно чуть подробнее?
Максимальный номер чего? Того номера, который был последний?
В коде, который ты привел стоит значение 0, это то значение, которое можно изменять на форме вручную, т.е. значением переменной можно сделать вводимое значение в определенной ячейке?
Автор: smirnvlad
Дата сообщения: 24.11.2010 16:18
если листы из книги не удалать, то по событию BeforePrint будет произведен поиск максимального сквозного номера на всех листах книги в ячейке ListNumCell , за минимум считаем (MaxNum+1 = 1), затем на все листах на которых не проставлено значение в ListNumCell, будет поставлено MaxNum, MaxNum+1...


Цитата:
это то значение, которое можно изменять на форме вручную, т.е. значением переменной можно сделать вводимое значение в определенной ячейке?

Если надо начать с N то MaxNum = N-1, или не удалять лист с максимальным значением и макрос сам его найдет среди всех листов, и продолжит нумерацию
Автор: febreze2009
Дата сообщения: 24.11.2010 17:19

Цитата:
если листы из книги не удалать, то по событию BeforePrint будет произведен поиск максимального сквозного номера на всех листах книги в ячейке ListNumCell , за минимум считаем (MaxNum+1 = 1), затем на все листах на которых не проставлено значение в ListNumCell, будет поставлено MaxNum, MaxNum+1...


Цитата:
это то значение, которое можно изменять на форме вручную, т.е. значением переменной можно сделать вводимое значение в определенной ячейке?

Если надо начать с N то MaxNum = N-1, или не удалять лист с максимальным значением и макрос сам его найдет среди всех листов, и продолжит нумерацию


Теперь по функционалу. Вставил скрипт в VBProject в книгу. Название книги и листов на английском. К ячейку А1 вставил номер в которому должен идти прирост. Нажимаю печать, выходит только тот номер, который указана в А1. Как запустить выполнение скрипта? Или его надо было кидать на кнопку на листе?

Автор: smirnvlad
Дата сообщения: 24.11.2010 17:47

Цитата:
Как запустить выполнение скрипта?

если он вставлен в объект ThisWorkbook, то срабатывает сам при нажатии на Просмотр или Печать, при этом номера должны заполниться на остальных листах
проверить запустился ли скрипт можно дописав
MsgBox "Before Print"
после Private Sub Workbook_BeforePrint(Cancel As Boolean)
при нажатии на просмотр должно появиться сообщение
Before Print с кнопкой Ok
Автор: febreze2009
Дата сообщения: 25.11.2010 09:09

Цитата:
Цитата:
Как запустить выполнение скрипта?

если он вставлен в объект ThisWorkbook, то срабатывает сам при нажатии на Просмотр или Печать, при этом номера должны заполниться на остальных листах
проверить запустился ли скрипт можно дописав
MsgBox "Before Print"
после Private Sub Workbook_BeforePrint(Cancel As Boolean)
при нажатии на просмотр должно появиться сообщение
Before Print с кнопкой Ok


Задача стоит немного не такая. На печать будет уходить информация только с одного листа. Там таблица, в одной из ячеек которой сквозная нумерация. Печатаешь например 10 экземпляров сегодня, нумерация 01-10, сохраняешь документ, завтра открываешь печатаешь еще 10-20, нумерация продолжается. Ну или прописываешь значение, с которого начинается нумерация сегодняшнего задания на печать.
Автор: smirnvlad
Дата сообщения: 25.11.2010 10:13
febreze2009
тогда надо не на событие до печати, а на кнопку назначить макрос при нажатии увеличивающий номер и показывающий диалог печати
[more]
в данном случае выводится диалог и если нажата ОК, то лист печатается с текущим номером, затем номер увеличится
ещё можно сначала увеличить номер, замет показать диалог
или отправить на печать без диалога с текущими настройками

Код: [no]
Sub НажатиеКнопки()
Dim MaxNum As Integer

ListNumCell = "A1"

' Считываем текущий номер
MaxNum = Range(ListNumCell).Value

' увеличиваем номер до печати
' Range(ListNumCell).Value = MaxNum + 1

' диалог печати
If Application.Dialogs(xlDialogPrint).Show Then
' или увеличиваем номер если печать не отменена
Range(ListNumCell).Value = MaxNum + 1
End If

' или печать листа без диалога печати
'ActiveSheet.PrintOut

End Sub
[/no]
Автор: febreze2009
Дата сообщения: 25.11.2010 16:30

Цитата:
febreze2009
тогда надо не на событие до печати, а на кнопку назначить макрос при нажатии увеличивающий номер и показывающий диалог печати
Подробнее...


Это ближе, и это работает спасибо.
Однако задача стоит печатать каждый раз разное количество листов. Их количество можно и 10, и 50, и 80.
Может есть возможность указать диапазон печатаемых значений. И пока этот диапазон не будет закончен печать будет продолжаться. Например: мне нужно сегодня распечатать листы с нумерацией скажем с 1011 по 1050. Диапазон либо указывается (с какого номера начать, каким закончить), либо указывается количество нужных листов (50) и номер с какого начать. Запускаем печать и все листы распечатываются со сквозной нумерацией.


Добавлено:

Цитата:
Цитата:
febreze2009
тогда надо не на событие до печати, а на кнопку назначить макрос при нажатии увеличивающий номер и показывающий диалог печати
Подробнее...


Это ближе, и это работает спасибо.
Однако задача стоит печатать каждый раз разное количество листов. Их количество можно и 10, и 50, и 80.
Может есть возможность указать диапазон печатаемых значений. И пока этот диапазон не будет закончен печать будет продолжаться. Например: мне нужно сегодня распечатать листы с нумерацией скажем с 1011 по 1050. Диапазон либо указывается (с какого номера начать, каким закончить), либо указывается количество нужных листов (50) и номер с какого начать. Запускаем печать и все листы распечатываются со сквозной нумерацией.


Немного покрутил, сделал. Спасибо всем за подсказки и предложенные решения.
у меня получилось как нельзя проще:


Код: Private Sub CommandButton1_Click()
Dim MaxNum As Integer

ListNumCell = "G2"
k = TextBox1.Value

For i = 1 To k

' Считываем текущий номер
MaxNum = Range(ListNumCell).Value

' увеличиваем номер до печати
Range(ListNumCell).Value = MaxNum + 1

' или печать листа без диалога печати
ActiveSheet.PrintOut

Next i
End Sub
Автор: smirnvlad
Дата сообщения: 25.11.2010 20:52
febreze2009
в свойствах принтера - дополнительно - использовать очередь печати - начинать печатать после помещения в очередь всего задания
если не поможет, то копировать всё на один временный лист, и печатать его

Страницы: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127

Предыдущая тема: VS 2010


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.