![]() |
#14 |
Moderator
|
Что ж, "утром - в газете, вечером - в куплете". Сваял я демонстрашку по этой задачке. Время сравнения двух множеств из заявленных 4500 элементов и перебора их расхождений у меня сплошь и рядом менее 1 секунды!
Перед запуском джоба необходимо зарегистрировать на компе упомянутую выше dll-ку AndyD'а (Построчный импорт из Excel через COM). После загрузки формы измените какие-нибудь ячейки (сотрите или замените иным текстом в ячейке). Закройте форму крестиком - в инфологе список расхождений. Имейте в виду, что время вывода в инфолог - "огромно" по сравнению с временем сравнения и перебора, поэтому оно и вынесено в отдельный цикл за пределы засечки по времени. X++: static void job_SpreadsheetAsTableProcessor(Args _args) { Form form = new Form(); FormBuildDesign formBuildDesign = form.addDesign('Design'); Args args = new Args(); FormRun formRun; FormActiveXControl ss; COM SafeArray = new COM('AxSafeArray.SafeArray'); COM range; COMVariant cvRange; COMVariant cvRow, cvCell; Array arr; int rowCount, colCount; int row, col; str val; Set setBefore = new Set(Types::Container); Set setAfter = new Set(Types::Container); Set setDiffer = new Set(Types::Container); SetEnumerator enumr; int timeStart, timeDuration; ; // динамически генерируем форму args.object(form); formRun = classFactory.formRunClass(args); formRun.init(); formRun.design().caption('Табличный процессор'); ss = formRun.design().addControl(FormControlType::ActiveX, 'Spreadsheet'); ss.className('{0002E541-0000-0000-C000-000000000046}'); // Microsoft Office Spreadsheet 10.0 //ss.className('{0002E559-0000-0000-C000-000000000046}'); // Microsoft Office Spreadsheet 11.0 ss.heightMode(FormHeight::ColumnHeight); ss.widthMode(FormWidth::ColumnWidth); range = ss.Range('A1:O300'); // 15 колонок - 300 строк range.Formula('="["&ROW()&","&COLUMN()&"]"'); // или, если будет ругаться, то: range.Formula('="["&СТРОКА()&","&СТОЛБЕЦ()&"]"'); cvRange = range.Value2(); rowCount = SafeArray.GetArrayRowCount(cvRange); colCount = SafeArray.GetArrayColCount(cvRange); // записываем состояние ячеек ДО изменения for (row=1; row<=rowCount; row++) { cvRow = SafeArray.GetArrayRow(cvRange, row); arr = cvRow.safeArray(); for (col=1; col<=colCount; col++) { cvCell = arr.value(col); setBefore.add([row, col, cvCell.bStr()]); } } formRun.run(); formRun.wait(); // здесь вручную изменяем несколько ячеек и закрываем форму крестиком timeStart = WinAPI::getTickCount(); // записываем состояние ячеек ПОСЛЕ изменения cvRange = range.Value2(); for (row=1; row<=rowCount; row++) { cvRow = SafeArray.GetArrayRow(cvRange, row); arr = cvRow.safeArray(); for (col=1; col<=colCount; col++) { cvCell = arr.value(col); setAfter.add([row, col, cvCell.bStr()]); } } // находим расхождения в состояниях setDiffer = Set::difference( setAfter, setBefore ); // "трогаем" все значения расхождений - как бы используем для каких-то наших целей enumr = setDiffer.getEnumerator(); while (enumr.moveNext()) { [row,col,val] = enumr.current(); } timeDuration = WinAPI::getTickCount() - timeStart; info(strFmt('Сравнение и перебор расхождений выполнены за %1 миллисек.', timeDuration)); setPrefix('Изменились следующие ячейки:'); // отдельным циклом, чтобы исключить время вывода в инфолог enumr = setDiffer.getEnumerator(); while (enumr.moveNext()) { [row,col,val] = enumr.current(); info(strFmt('Строка: %1 -- Столбец: %2 -- Новое значение: %3', row, col, val)); } } ![]() P.S. А если фрагмент вывода в инфолог слегка изменить, то удобнее (по крайней мере, с точки зрения тестирования) будет вывести адрес ячейки вместо номеров строки и столбца: X++: COM cells, cell; // добавлено ........... setPrefix('Изменились следующие ячейки:'); // отдельным циклом, чтобы исключить время вывода в инфолог cells = ss.Cells(); // добавлено enumr = setDiffer.getEnumerator(); while (enumr.moveNext()) { [row,col,val] = enumr.current(); cell = cells.Item(row,col); // добавлено info(strFmt('Адрес: %1 -- Новое значение: %2', cell.Address(false,false), val)); // изменено } Последний раз редактировалось Gustav; 21.05.2010 в 19:33. |
|
|
За это сообщение автора поблагодарили: Serg (1), Poleax (1). |
|
![]() |
||||
Тема | Ответов | |||
aEremenko: Как обнаружить какой пользователь загружает процессор AOS? | 4 | |||
Табличный Mapping - список используеиых таблиц | 6 |
|