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

» Excel VBA

Автор: aks_sv
Дата сообщения: 23.12.2006 17:38
Troitsky
Огромное человеческое СПАСИБО:
Изменил:
r = ListBox1.ListCount - 1
И все ОК
Автор: Aladdinych
Дата сообщения: 25.12.2006 12:49
Как повысить производительность?
У меня в модуле по открытию книги, копируются данные из Лист1 одной книги в Лист1 другой книги. Всего ~ 1300 строк. Занимает эта процедура 35 сек. На компьютере с проц Pentium IV 1.8 Ггц. Перед копированием вычисление формул отключаю. После копирования включаю.
Что еще можно предпринять, чтобы увелитить производительность модуля?
Автор: Troitsky
Дата сообщения: 25.12.2006 13:26
Aladdinych

Цитата:
У меня в модуле по открытию книги, копируются данные из Лист1 одной книги в Лист1 другой книги.

А как копируешь? Диапазоном или каждую ячейку поотдельности?
Один из способов оптимизации есть в шапке. Но не видя кода трудно что то советовать.
Автор: The okk
Дата сообщения: 25.12.2006 13:52
Aladdinych
А нельзя лист1 одной книги скопировать в другую целиком (в крайнем случае, потом удалить ненужное)? Копирование листа занимает времени на порядок меньше, чем перенос данных/форматов.
Ну, разумеется, не забываем про Application.Screenupdating = False перед началом копирования и Application.Screenupdating = True после. Небольшой прирост в скорости будет, если в качестве переменных для счетчиков будешь использовать Long.

Добавлено:
но лучше, конечно, покажи код
Автор: Aladdinych
Дата сообщения: 25.12.2006 14:42
Troitsky
Раньше копировал ячейка в ячейку.
Сейчас копирую построчно диапазоном.
The okk
Лист в лист скопировать нельзя. Первая книга на самом деле просто dbf таблица.
Использование Screenupdating сократило время обработки до 15-16 сек.
Для копирования использовал цикл While Wend.



Добавлено:
И еще почему-то не работает строка
newdoc.ActiveSheet.Range(Cells(i + 4, 2), Cells(i + 4, 11)).Value = .Workbooks(wbdbf).ActiveSheet.Range(Cells(i + 2, 2), Cells(i + 2, 11)).Value

а вот строка
newdoc.ActiveSheet.Range("B" + Trim(Str(i + 4)) + ":K" + Trim(Str(i + 4))).Value = .Workbooks(wbdbf).ActiveSheet.Range("B" + Trim(Str(i + 2)) + ":K" + Trim(Str(i + 2))).Value
работает. Что не правильно в первом варианте?



Добавлено:
Выдается ошибка application defined or object defined error

Добавлено:
И еще
из 15 сек на копирование уходит только 4 сек все остальное уходит на загрузку/сохранение файлов.
Автор: The okk
Дата сообщения: 25.12.2006 17:19
Aladdinych

Цитата:
Лист в лист скопировать нельзя.

можно копировать лист в книгу


Цитата:
Для копирования использовал цикл While Wend.

циклы while использовать не стоит. Только For
Автор: WWWovan
Дата сообщения: 26.12.2006 11:50
Итересует каким образом можно поменять имя файла с Bill1, Bill2, Bill3.... на осмысленное "Счет №....."?
Можно ли это сделать при формировнии счета прикладной программы написаной на CBuilder?
Или нужно использовать макросы?

З.Ы. Документ формируется на основании шаблона.

Пожалуйста сильно не пинайте. С VBA раньше дела не имел, а сейчас возникла необходимость.

Заранее спасибо за помощь.
Автор: jONES1979
Дата сообщения: 26.12.2006 14:46
WWWovan

в билдере функция RenameFile
перебор файлов в каталоге через FindFirst, FindNext, FindClose

почему в ЭТОЙ ветке спросил?

или ты про что вообще?
Автор: WWWovan
Дата сообщения: 26.12.2006 14:53

Цитата:
WWWovan

в билдере функция RenameFile
перебор файлов в каталоге через FindFirst, FindNext, FindClose

почему в ЭТОЙ ветке спросил?

или ты про что вообще?


Я не совсем корректно сформулировал вопрос.
Есть счет.
При помощи кнопочки на форме вызывается экспорт счета в Эксель на основании шаблона Bill.xlt. Он сохраняется уже из Excel. И получает по умолчаниюю имена Bill1.xls, Bill2.xls и т.д.
Я же хочу, чтобы при вызове диалога "Сохранить" в Excelе в имя файла по умолчанию подставлялся номер счёта.
Автор: jONES1979
Дата сообщения: 27.12.2006 12:02
WWWovan


Добавлено:
WWWovan

Цитата:
При помощи кнопочки на форме вызывается экспорт счета в Эксель на основании шаблона Bill.xlt. Он сохраняется уже из Excel.


при помощи "той же самой кнопочки" ты можешь не только эскпортировать, но и заранее сохранить файл с выбранным именем, ДО того как юзеру этот счет выскочит для правки в excele...

в какой момент это лучше сделать, зависит от твоей "технологии экспорта".
покажи код.
Автор: WWWovan
Дата сообщения: 27.12.2006 12:57
jONES1979

Цитата:
при помощи "той же самой кнопочки" ты можешь не только эскпортировать, но и заранее сохранить файл с выбранным именем, ДО того как юзеру этот счет выскочит для правки в excele...


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

Ниже код...

Цитата:

void __fastcall TBillForm::sbCopyToExcelClick(TObject *Sender)
{
TKeyboardState KeyState;
GetKeyboardState(KeyState);
bool SendEMail = KeyboardStateToShiftState(KeyState).Contains(ssCtrl);
if(ActiveControl==BillTGrid)
BillTGrid->OnExit(Sender);
ToBillRecord();
CConfigEntry *CfgRec = new CConfigEntry;
CfgRec->Load("TEMPLPATH");
String TemplateName = CfgRec->Value + String("\\BILL.XLT");
delete CfgRec;
Variant App, Sh;
App = ExcelInit();
if(App.IsNull()) {
Application->MessageBox("Невозможно открыть Microsoft Excel. "
"Возможно, это приложение на компьютере не установлено.","Ошибка",MB_OK+MB_ICONERROR);
return;
}
Sh = ExcelAddWB(App,TemplateName);
if(Sh.IsNull()) {
Application->MessageBox("Ошибка при создании книги Microsoft Excel.","Ошибка",MB_OK+MB_ICONERROR);
return;
}
toExcel(App,"НомерСчета","Рахунок-фактура "+BillRec.Num+" від "+DateToStr(BillRec.Date)+".");
CClientEntry *ClRec = new CClientEntry;
ClRec->Load(BillRec.Client);
toExcel(App,"Плательщик",ClRec->LegalName);
toExcel(App,"ТелПлательщика",ClRec->Tel);
toExcel(App,"ФаксПлательщика",ClRec->Fax);
String ClEMail = Trim(ClRec->EMail);
delete ClRec;
if(Trim(ClEMail)!="")
ExcelHyperLink(App,"Плательщик","mailto:"+Trim(ClEMail));
toExcel(App,"ИтогоБезНДС",FloatToStrMExcel(BillRec.Amount/NDS_Mul));
toExcel(App,"НДС",FloatToStrMExcel(BillRec.Amount-BillRec.Amount/NDS_Mul));
toExcel(App,"Итого",FloatToStrMExcel(BillRec.Amount));
toExcel(App,"ИтогоПрописью",CurrToStrM(BillRec.Amount));
toExcel(App,"Исполнитель",BillRec.AutorName);
ExcelAddRows(App,"НомТовара",BillRec.Recs->Count-1);
CBillTEntry *BillTRec;
for(int i=0;i<BillRec.Recs->Count;i++) {
BillTRec = BillRec.Recs->Item(i);
toExcel(App,"НомТовара",i,(IntToStr(i+1)+".").c_str());
toExcel(App,"НазвТовара",i,BillTRec->WareName.c_str());
toExcel(App,"ЦенаТовара",i,FloatToStrMExcel(BillTRec->Price/NDS_Mul));
toExcel(App,"КолТовара",i,BillTRec->Count);
toExcel(App,"СуммаТовара",i,FloatToStrMExcel(BillTRec->Amount/NDS_Mul));
}

App.OlePropertySet("Visible",true);
}
Автор: Anton T
Дата сообщения: 27.12.2006 15:00
Как сделать прогресс после инициализации строки в листе? (Например, в листе 40000 строк.) А у меня есть другие прогрессы для создание массивы, а строки нет.
Автор: jONES1979
Дата сообщения: 28.12.2006 14:32
WWWovan

а обрати внимание: когда Ексель УЖЕ выскочил юзеру для правки, в заголовке НЕТ ЛИ УЖЕ имени Bill1 [Bill2, Bill3, etc].
Догадываюсь, что оно уже бужет сформировано по умолчанию, но подтверди, в твоём случае это так?

Добавлено:

Цитата:
В том то и дело, что заранее файл сохранять не нужно
, ну если это категорично, то да.. делать надо уже в экселе
Автор: WWWovan
Дата сообщения: 28.12.2006 14:46
jONES1979

Цитата:
а обрати внимание: когда Ексель УЖЕ выскочил юзеру для правки, в заголовке НЕТ ЛИ УЖЕ имени Bill1 [Bill2, Bill3, etc].
Догадываюсь, что оно уже бужет сформировано по умолчанию, но подтверди, в твоём случае это так?


Да. Присутствует.


Цитата:
делать надо уже в экселе


Вопрос в том как?
Автор: giash
Дата сообщения: 29.12.2006 11:01
Здравствуйте! С наступающим! Понимаю, что, скорее всего, в ближайшее время ответа мне не дождаться. Но все же
У меня возникла такая проблема: мне необходимо ежемесячно вставлять лист из одной книги в другую ввиде ссылок. нельзя ли сделать так, чтобы в определенной ячейке листа в который переносятся данные вводить название файла, напр. januari, из которого эти данные берутся, благодаря чему обновление будет осуществляться автоматически.
Заранее всем благодарен
Еще раз с новым годом!
Автор: The okk
Дата сообщения: 29.12.2006 11:31
giash

Цитата:
Понимаю, что, скорее всего, в ближайшее время ответа мне не дождаться.

Зря ты так думаешь.

Цитата:
мне необходимо ежемесячно вставлять лист из одной книги в другую ввиде ссылок.

Так все-таки вставлять лист? Или работать с ссылками? Если дело только в ссылках, макросы не нужны.

Цитата:
нельзя ли сделать так, чтобы в определенной ячейке листа в который переносятся данные вводить название файла, напр. januari, из которого эти данные берутся, благодаря чему обновление будет осуществляться автоматически.

Почему бы и нет. Пиши название файла в отдельной ячейке, а на листе все формулы, ссылающиеся на лист, пиши в виде: =ДВССЫЛ(ячейка с названием) & нужная ячейка этого листа.
Например:
У нас есть файлы 1.xls, 2.xls и 3.xls. Нам нужно в файле 1.xls сделать ссылки на третий лист второй книги, потом заменить в ссылках вторую книгу на третью.
В отдельной ячейке (например, A1) любого (например, третьего) листа первой книги создаем ссылку на третий лист второй книги: [2.xls]Лист3! (БЕЗ знака "=")
А формулы в первой книге пишем в виде: =ДВССЫЛ(A1 & "ячейка_листа"), где A1 - ячейка со ссылкой на книгу, ячейка_листа - адрес ячейкй в указанной книге.
Вот, собственно, и все. Теперь достаточно изменить адрес в ячейке A1 на [3.xls]Лист3!, чтобы адреса во всех ссылках поменялись.
Автор: giash
Дата сообщения: 29.12.2006 11:40
Огромное спасибо! Правда, не ожидал. Распечатал и буду разбираться с вашими рекомендациями. Уверен, что сработает.
С уважением
Автор: The okk
Дата сообщения: 29.12.2006 12:12
Если кто-то с ListView работает и дружит с английским, тут обсуждают этот контрол. Да и в целом, интересный сайт.

giash
да собсвенно и не за что. Если все правильно сделаешь - будет работать, поскольку проверил на практике.
Автор: jONES1979
Дата сообщения: 29.12.2006 15:29
The okk

может быть обрабатывать _BeforeSave в макросах. Завтра на трезвую голову подумаю-потестирую...
Автор: The okk
Дата сообщения: 29.12.2006 19:15
jONES1979
Зачем? Если проблема только в ссылках, то формул вполне достаточно и не надо заморачиваться, поскольку формулы работают на порядки быстрее аналогичных конструкций VBA
Автор: jONES1979
Дата сообщения: 29.12.2006 23:30
The okk
это про что ты?
Автор: Pazan
Дата сообщения: 30.12.2006 08:59
1. как с помощью VBA скопировать значение выделенной ячейки в буфер обмена?
2. как с помощью VBA удалить с файла всю личную информацию: автор, автор правки, версий и т.д.?

Автор: jONES1979
Дата сообщения: 30.12.2006 10:27
Pazan

Цитата:
1. как с помощью VBA скопировать значение выделенной ячейки в буфер обмена?


Код: Range("C7").Select
Selection.Copy
Автор: The okk
Дата сообщения: 30.12.2006 13:18
jONES1979
а ты про что?
Автор: Pazan
Дата сообщения: 30.12.2006 14:51
jONES1979

Цитата:
Range("C7").Select
Selection.Copy

это я знаю, но оно копирует всю ячейку, включая форматирование и т.п., потому когда я из клипборда вставляю в Ворд/Райтер -- вставляэется вся ячейка. А мне нужно то что я делаю: нажимаю F2, выделяю текст, правой кнопкой "Копировать". тогда вставляется только знеформатированное значение
Автор: SERGE_BLIZNUK
Дата сообщения: 30.12.2006 16:33
Pazan
Цитата:
но оно копирует всю ячейку, включая форматирование и т.п.<...> А мне нужно то что я делаю: нажимаю F2, выделяю текст, правой кнопкой "Копировать". тогда вставляется только неформатированное значение
Похоже, что чисто на Excel это нельзя сделать ;-(( получить неформатированное значение это проще простого (.Value) , а вот кинуть что-то в буфер обмена - проблема... Если уж очень надо (подчёркиваю ОЧЕНЬ - могу предложить крайне извращённый вариант через копирование в буфер обмена с помощью вызова через ShellExecute дополнительной программы (могу кинуть), задача которой будет просто помещать данные из командной строки в буфер обмена... но всё это крайне извратно...

Автор: jONES1979
Дата сообщения: 30.12.2006 21:58
SERGE_BLIZNUK

есть альтернативный, но тоже "ОТНОСИТЕЛЬНО" извратный вариант, копировать через explorer-объект. По крайней мере, его можно создать один глобальный и пользоваться.

Код:
strCopy = "This text has been copied to the clipboard."

Set objIE = CreateObject("InternetExplorer.Application")
objIE.Navigate("about:blank")
objIE.document.parentwindow.clipboardData.SetData "text", strCopy
' objIE.Quit
Автор: crewgehr
Дата сообщения: 30.12.2006 23:02
Здрасьте!
Всех с наступающим НГ!
Можно ли оптимальнее записать код, который будет очищать значения в диапазоне из 2-х столбцов с определенным шагом? А ещё лучше, чтоб столбцы удалялись напрочь

C1 = 6 ' 1st deleted column
C2 = 7 ' 2nd deleted column
R1 = 3 ' 1st row
For C1 = 6 To 36 Step 3
For R1 = 3 To 227
For C2 = 7 To 37 Step 3
Cells(R1, C1).ClearContents
Cells(R1, C2).ClearContents
Next C2
Next R1
Next C1

Автор: SERGE_BLIZNUK
Дата сообщения: 31.12.2006 00:48

Цитата:
записать код, который будет очищать значения в диапазрне из 2-х столбцов

так как стобцы рядом и чистить их надо на одинаковую высоту, то конкретно ваш код можно оптимизировать так:

Код:
Sub ClearRange()
R1 = 3
R2 = 227
For C1 = 6 To 36 Step 3
Range(Cells(R1, C1), Cells(R2, C1 + 1)).ClearContents
Next C1
End Sub
Автор: AndreyIVN
Дата сообщения: 31.12.2006 02:24
Не подскажете, как сделать так, чтобы для аргументов пользовательских функций отображалось описание, как это сделано для встроенных функций?

Единственное что я нашел, как отображать описание всей функции в целом - в обозревателе объектов - свойства функции - description, и то, почему-то это описание появляется только после экспортирования модуля в файл .bas и последующем его импорте обратно в проект (в файле .bas появляется строка типа - Attribute Имя_функции.VB_Description = "Описание функции")
Все эксперименты с этой строкой (попытки подставлять имена аргументов вместо имени функции и т.п.) успехом не увенчались.

.

Страницы: 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768

Предыдущая тема: Стоит ли переходить с Билдера на Делфи?


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