Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Microsoft Office и VBA программирование > Microsoft Office Word
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Закрытая тема
Ваша тема закрыта, почему это могло произойти? Возможно,
Нет наработок или кода, если нужно готовое решение - создайте тему в разделе Фриланс и оплатите работу.
Название темы включает слова - "Помогите", "Нужна помощь", "Срочно", "Пожалуйста".
Название темы слишком короткое или не отражает сути вашего вопроса.
Тема исчерпала себя, помните, один вопрос - одна тема
Прочитайте правила и заново правильно создайте тему.
 
Опции темы Поиск в этой теме
Старый 30.10.2008, 12:28   #1
Nemez
Пользователь
 
Аватар для Nemez
 
Регистрация: 11.02.2008
Сообщений: 69
По умолчанию А можно побыстрей?

Приветствую. Вопрос значит следующий. Буквально вчера мне пришлось программно считывать данные из таблицы Word. Столбцов 14, строк 3418.
Вообщем запустил я программу для чтения данных из ворда за 2 часа до конца рабочего дня, но так и не дождался окончания сего процесса и оставил комп на ночь. На чтение одной строки уходит где-то 3 секунды. Вопрос: Можно ли как-то ускорить этот процесс и почему такие тормоза?
Когда я сохраняю/загружаю эти 3000 строк из стринггрида в/из обычный(ого) txt это занимает пару секунд, а тут так долго. Комп нормальный.
Nemez вне форума
Старый 30.10.2008, 18:26   #2
EducatedFool
Программист VBA
СуперМодератор
 
Аватар для EducatedFool
 
Регистрация: 13.07.2008
Сообщений: 6,856
По умолчанию

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

Я вот решил проверить следующий код:
Код:
Sub test()
    'MsgBox Me.Tables(1).Rows.Count
    For i = 1 To Me.Tables(1).Rows.Count
        res = Me.Tables(1).Rows(i).Range.Text
        Debug.Print "row = " & i    ', res
    Next i
End Sub
на таблице из 15 столбцов и 300 строк.
До 200-й строки считывалось 10-20 строк в секунду, а потом начинались тормоза. (Word2003, WinXP)...
После нескольких запусков кода тормоза начинаются раньше (с 90-й строки)...

На системах типа Win98 некоторые тормоза Worda были объяснимы (исчерпывались ресурсы GDI и т.д.), а здесь вот я тоже понять не могу - из-за чего тормозит?
EducatedFool вне форума
Старый 31.10.2008, 06:19   #3
Nemez
Пользователь
 
Аватар для Nemez
 
Регистрация: 11.02.2008
Сообщений: 69
По умолчанию

Цитата:
Сообщение от EducatedFool Посмотреть сообщение
Сложно сказать, не увидев кода...
Ну вот собствено и код, ну я думаю дело не в нем. Получается что чем больше весит документ ворда, т.е. чем больше строк тем больше тормоза.
Для примера:1400 строк около 20 минут, а 3500 около 3 часов идет считывание.
Код:
j:=WordDocument1.Tables.Item(1).Rows.Count;    // количество строк
   for i:=1 to j-1 do
       BEGIN
  IdFT:=WordDocument1.Tables.Item(1).Cell(i,4).Range.Text;//идентификатор
  kolvo:=WordDocument1.Tables.Item(1).Cell(i,3).Range.Text;//количество
  D1:=WordDocument1.Tables.Item(1).Cell(i,5).Range.Text;//D1
  D2:=WordDocument1.Tables.Item(1).Cell(i,6).Range.Text;//D2
  D3:=WordDocument1.Tables.Item(1).Cell(i,8).Range.Text;//D3
  dlinl:=WordDocument1.Tables.Item(1).Cell(i,13).Range.Text;//длина
  dlinlp:=WordDocument1.Tables.Item(1).Cell(i,14).Range.Text;//длина перехода
  a:=WordDocument1.Tables.Item(1).Cell(i,6).Range.Text;//A
  b:=WordDocument1.Tables.Item(1).Cell(i,5).Range.Text;//B
  c:=WordDocument1.Tables.Item(1).Cell(i,9).Range.Text;//C
  d:=WordDocument1.Tables.Item(1).Cell(i,8).Range.Text;//D
  e:=WordDocument1.Tables.Item(1).Cell(i,13).Range.Text;//e
  f:=WordDocument1.Tables.Item(1).Cell(i,14).Range.Text;//f
  h:=WordDocument1.Tables.Item(1).Cell(i,11).Range.Text;//f
  ugdl:=WordDocument1.Tables.Item(1).Cell(i,15).Range.Text;//Угол
       END;
Nemez вне форума
Старый 31.10.2008, 10:55   #4
EducatedFool
Программист VBA
СуперМодератор
 
Аватар для EducatedFool
 
Регистрация: 13.07.2008
Сообщений: 6,856
По умолчанию

Имеет смысл попробовать считать весь текст таблицы в переменную, а потом обрабатывать текстовую строку.

Например, так:

Код:
Sub test()
    Dim arr1 As Variant, arr2 As Variant, res As String
    'MsgBox Me.Tables(1).Rows.Count' отображает количество строк в таблице

    res = Me.Tables(1).Range.Text    ' считываем текст таблицы в переменную

    ' разбиваем массив на строки таблицы
    arr1 = Split(res, Chr$(13) & Chr$(7) & Chr$(13) & Chr$(7))

    'MsgBox UBound(arr1) ' отображает количество распознанных строк в таблице

    For i = 1 To UBound(arr1)
        'Debug.Print "Содержимое строки " & i, arr1(i)
        arr2 = Split(arr1(i), Chr$(13) & Chr$(7))
        For j = 1 To UBound(arr2)
            Debug.Print "строка = " & i, "столбец " & j, "Значение ячейки: " & arr2(j)
        Next j
    Next i
End Sub
Этот код помещаем в модуль ThisDocument файла, содержащего таблицу.
Отрабатывает код моментально (если, конечно, вместо вывода значений через Debug.Print записывать эти значения сразу в переменные)

Перевести код с VBA, думаю, проблем не составит.
EducatedFool вне форума
Старый 31.10.2008, 12:15   #5
Nemez
Пользователь
 
Аватар для Nemez
 
Регистрация: 11.02.2008
Сообщений: 69
По умолчанию

Спасибо хорошая идея. Обязательно попробую
Nemez вне форума
Старый 31.10.2008, 15:35   #6
EducatedFool
Программист VBA
СуперМодератор
 
Аватар для EducatedFool
 
Регистрация: 13.07.2008
Сообщений: 6,856
По умолчанию

Забыл сказать - в предложенном коде есть недоработка...

При разбивке переменной res на строки arr1 = Split(res, Chr$(13) & Chr$(7) & Chr$(13) & Chr$(7))
используется разделитель Chr$(13) & Chr$(7) & Chr$(13) & Chr$(7)),
который также может встретиться в переменной res, если попадётся пустая ячейка в строке.

То есть, если в таблице есть 5 пустых ячеек, то
MsgBox Me.Tables(1).Rows.Count выдаст верный результат (например, 1300),
а MsgBox UBound(arr1) выдаст 1305

Я вычислил разделитель строк путём анализа кодов символов строки res - и получил строку-разделитель Chr$(13) & Chr$(7) & Chr$(13) & Chr$(7), но, возможно, есть более правильный способ определения конца строки по тексту таблицы.

Вообще, должно быть более простое (и в то же время быстрое) решение описанной Вами задачи... может, кто подскажет...

Ну а если всё же использовать предложенный мной вариант, то можно избежать проблемы, изначально разбивая строку res на части, используя разделитель Chr$(13) & Chr$(7) - получится массив с количеством элементов, равным количеству ячеек (возможно, придётся удалить пустые элементы массива). После этого, зная количество столбцов, уже несложно в цикле обработать полученные данные.
EducatedFool вне форума
Закрытая тема


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Можно ли оптимизировать формулу? дмидми Microsoft Office Excel 3 12.08.2008 11:28
Можно ли его расшифровать? DenCraft Фриланс 4 24.02.2008 01:19
можно ли такое реализовать Димарик Общие вопросы Delphi 6 22.07.2007 13:18
Можно ли программировать? Умелец Свободное общение 13 23.03.2007 19:52
RichEdit. как можно вставлять картинку туда? как можно Скрол програмно вниз двигать? Svop Компоненты Delphi 7 28.11.2006 21:07