powered by simpleCommunicator - 2.0.18     © 2024 Programmizd 02
Map
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Очень долгий перебор строк в цикле
12 сообщений из 62, страница 3 из 3
Очень долгий перебор строк в цикле
    #40083250
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
я вижу копипасту внутри цикла
Markovich21
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
        For i = 10 To s
            t = ThisWorkbook.Worksheets("Лист1").Cells(i + 1, 10) + 1
            
            .Cell(t, 2).Range.Copy
            WrdDoc.Range(.Cell(t, 1).Range.Start, .Cell(t, 6).Range.End).Delete
            .Cell(t, 1).Merge MergeTo:=WrdApp.ActiveDocument.Tables(3).Cell(t, 6)
            .Cell(t, 1).Range.PasteAndFormat (16)
        Next

...
Рейтинг: 0 / 0
Очень долгий перебор строк в цикле
    #40083257
Markovich21
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Shocker.Pro, тут работает таким образом, что таблица в ворд уже полностью вставлена, а t номер строки (берущийся из экселя), в которой нужно объединить ячейки. Сначала какое то общее наименование (оно находится во втором столбце), которое должно быть в объединенной строке копируется в буфер, ячейки строки очищаются, объединяются и наименование вставляется обратно в уже объединенную ячейку. У меня родился такой вот алгоритм работы, другой как то в голове не складывается. Можно как то по другому лучше сделать?
...
Рейтинг: 0 / 0
Очень долгий перебор строк в цикле
    #40084316
Markovich21
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Shocker.Pro, Скажите, пожалуйста, вставить диапазон ячеек в таблицу ворд, не используя буфер обмена, а через переменную теоретически возможно? у меня при попытках что то подобное сделать выпадают либо ошибки, либо ничего не вставляется, хотя по одной ячейке вставка в ячейку таблицы ворд через переменную происходит без проблем. Предполагаю, что выделение диапазона ячеек в ворде таким образом:
Код: vbnet
1.
WrdDoc.Range(.Cell(2, 2).Range.Start, .Cell(r, 6).Range.End)

не подходит для вставки переменной.
...
Рейтинг: 0 / 0
Очень долгий перебор строк в цикле
    #40084611
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вставить текст можно через переменную или прямо напрямую, присвоив значение свойства Text. Но форматирование не сохранится
...
Рейтинг: 0 / 0
Очень долгий перебор строк в цикле
    #40084613
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Но вообще я этот код тестировал на прошлой неделе, там львиная часть времени уходит не на цикл, а на вставку приличного размера данных из буфера обмена
...
Рейтинг: 0 / 0
Очень долгий перебор строк в цикле
    #40087830
Markovich21
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Shocker.Pro, спасибо за помощь. по Вашему совету избавился от копирования в цикле, использовав переменную и массив. Никак не получается вставлять данные минуя буфер обмена (через переменную), значение свойства Text. применять пробовал. Подскажите, пожалуйста, имеет ли смысл пытаться вставлять данные через переменную, будет ли на этом прирост скорости? На данный момент рабочий код выглядит так:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
Sub ToWordTbl()

tm = Timer

Dim WrdApp As Word.Application
Dim WrdDoc As Word.Document
Dim WrdTbl As Word.Table
Dim DocPath As String, d As String
Dim n As Integer, s As Integer
Dim str() As Variant
        
        n = Worksheets("Лист1").Range("A10")
        If n = 0 Then
            MsgBox "Таблица пустая"
        Exit Sub
        End If
    
    With Worksheets("Лист1")
        s = .Range("J10") + 12
        .Cells(11, 1).Resize(n, 5).Copy
        str = .Range(Cells(11, 10), Cells(s, 10)).Value
    End With
    
    DocPath = ThisWorkbook.Path & "\"
    
    On Error Resume Next
    Set WrdApp = GetObject(, "Word.Application")
        If WrdApp Is Nothing Then Set WrdApp = CreateObject("Word.Application")
    Set WrdDoc = WrdApp.Documents.Open(DocPath & "Приемник.docx")
        If WrdDoc Is Nothing Then Set WrdDoc = WrdApp.Documents.Open(DocPath & "Приемник.docx")
    On Error GoTo 0

    WrdApp.Visible = False
    
        If Dir(DocPath & "Приемник.docx") = "" Then
            MsgBox "Файл ""Приемник.docx"" отсутствует"
            Application.CutCopyMode = False
            WrdApp.Visible = True
            Exit Sub
        End If
      
    Set WrdTbl = WrdDoc.Tables(3)
    With WrdTbl

        If .Rows.Count > 2 Then
            MsgBox "Ошибка шаблона ""Приемник""."
            Application.CutCopyMode = False
            WrdApp.Visible = True
            Exit Sub
        End If
        
        .Rows(2).Select
            On Error Resume Next
            WrdApp.Selection.InsertRowsBelow n - 1
            On Error GoTo 0
        
        WrdDoc.Range(.Cell(2, 2).Range.Start, .Cell(n + 1, 6).Range.End).PasteAndFormat (16)

        .Rows(1).Borders(wdBorderBottom).LineStyle = wdLineStyleDouble
        .Rows(n + 1).Borders(wdBorderBottom).LineStyle = wdLineStyleDouble
               
        For i = 1 To UBound(str) - 2
            d = .Cell(str(i, 1) + 1, 2).Range
            .Cell(str(i, 1) + 1, 1).Merge MergeTo:=WrdApp.ActiveDocument.Tables(3).Cell(str(i, 1) + 1, 6)
            d = Left(d, Len(d) - 2)
            .Cell(str(i, 1) + 1, 1).Range = d
        Next

    End With

    With Application
        .CutCopyMode = False
    End With

    WrdApp.Visible = True

MsgBox Timer - tm, 64


End Sub
...
Рейтинг: 0 / 0
Очень долгий перебор строк в цикле
    #40087838
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Через переменную можно перенести текст, но не полностью набор ячеек и строк со всем форматированием и т.п.
...
Рейтинг: 0 / 0
Очень долгий перебор строк в цикле
    #40087857
Markovich21
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Shocker.Pro,
создаю переменную:
Код: vbnet
1.
Dim tbl As Variant


вместо копирования в буфер строка:
Код: vbnet
1.
tbl = .Cells(11, 1).Resize(n, 5).Text


и в строке ошибка:
Код: vbnet
1.
WrdDoc.Range(.Cell(2, 2).Range.Start, .Cell(n + 1, 6).Range.End) = tbl



Получается сделал я примерно так как работало бы в экселе. С вордом так не работает, как Вы говорите, передается только текст. Еще помимо вставки из буфера значимую часть времени занимает объединение ячеек, что тоже, наверное, не ускоришь.
Выходит, что в плане оптимизации и увеличения скорости больше особо ничего не выжмешь и можно оставить код как есть?
...
Рейтинг: 0 / 0
Очень долгий перебор строк в цикле
    #40087879
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Markovich21
Получается сделал я примерно так как работало бы в экселе. С вордом так не работает, как Вы говорите, передается только текст.
Дело не в экселе или ворде, а в том, что их ячейки - это объекты совершенно разного типа.


Markovich21
Выходит, что в плане оптимизации и увеличения скорости больше особо ничего не выжмешь и можно оставить код как есть?
Во-первых было предложено:
Antonariy
Индексированные свойства тормозят. Потому что при обращении по индексу где-то внутри происходит перебор. Чтобы не тормозило, нужно использовать for each.
я сам не экспериментировал. Возможно, можно ускорить, попытавшись избавиться от обращениям к ячейкам по индексам.

Можно покурить "слияние", оно вроде как предназначено для того, чтобы перекидывать данные в такой ситуации. Сам не работал с ним.

Можно попытаться работать со стороны Ворда (то есть чтобы код был не в экселе, а в ворде, затянуть данные из экселевского файла через ADODB, обработать их в памяти и вывести в таблицу)

Можно сформировать html-файл и открыть его в ворде. Я делал так универсальные отчеты, которые можно было открывать в браузере, ворде и экселе, при этом они выглядели более-менее одинаково. Там, правда, очень странная интерпретация html, например в тэге в атрибуте класса может быть только один класс, остальные игнорируются, поэтому для документа приходилось создавать персональную таблицу классов, но в целом удавалось объединять и раскрашивать ячейки таблицы и осуществлять кое-какое форматирование

Так что есть куда копать, всё зависит от времени и желания
...
Рейтинг: 0 / 0
Очень долгий перебор строк в цикле
    #40087928
Markovich21
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Shocker.Pro, спасибо, за наметки. Запуск макроса со стороны ворда отпадает, под мой случай не подходит, а вот другие варианты буду изучать
...
Рейтинг: 0 / 0
Очень долгий перебор строк в цикле
    #40087947
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В конце-концов можно напрямую формировать docx-файл, так как это просто zip-архив с кучкой xml-внутри. Но без какой-нибудь OpenXML-библиотеки, которая упростит формирование файлов - это адский труд. Да и с библиотекой не сахар, в общем-то. Зато это точно будет самый быстрый вариант ))
...
Рейтинг: 0 / 0
Очень долгий перебор строк в цикле
    #40088149
Markovich21
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Shocker.Pro, спасибо, но последний вариант это уже выше моих видений о возможностях vba, сложно представляю о чем идет речь.
...
Рейтинг: 0 / 0
12 сообщений из 62, страница 3 из 3
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Очень долгий перебор строк в цикле
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали тему (1): Анонимы (1)
Читали форум (2): Анонимы (2)
Пользователи онлайн (12): Анонимы (11), Yandex Bot 4 мин.
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]