Форум программистов, компьютерный форум, киберфорум
VBA
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.76/25: Рейтинг темы: голосов - 25, средняя оценка - 4.76
 Аватар для blackeangel
19 / 10 / 1
Регистрация: 22.07.2015
Сообщений: 908

Ускорить работу макроса

30.11.2017, 16:27. Показов 5818. Ответов 117
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Как ускорить работу скрипта?
Visual Basic
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
Sub test()
    Dim arr1()
    Application.ScreenUpdating = False
    'range и массив рабочей книги
    ncolumn = Rows(1).Find(What:="Обозначение", LookIn:=xlValues, LookAt:=xlWhole).Column
    Columns(ncolumn + 1).Insert 'вставляем столбец справа
    Cells(1, ncolumn + 1).Value = "Карточки" 'вставляем заголовок столбца
    m = ActiveSheet.Cells(Rows.Count, ncolumn).End(xlUp).Row
    Set rn = ActiveSheet.Cells(2, ncolumn).Resize(m, 2)
    arr2 = rn.Value
    Set conn = New ADODB.Connection     'Создание соединения
    conn.ConnectionString = "Provider=SQLOLEDB.1;Password=132132;Persist Security Info=True;User ID=User;Initial Catalog=dbScanKD;Data Source=SQL05" 'Строка подключения
    conn.Open   'Открытие соединения
    Set rst = New ADODB.Recordset ' Создание объекта Recordset.
    rst.ActiveConnection = conn ' Подключение этого объекта к ранее открытому каналу связи.
    Ask = "SELECT DISTINCT [Oboznach] FROM [dbScanKD].[dbo].[vwScanKD] Where Not ([Oboznach] Like '%СБ'or [Oboznach] Like '%ТУ' or [Oboznach] Like '%ИМ' or [Oboznach] Like '%ДИ' or [Oboznach] Like '%РР' or [Oboznach] Like '%РИ' or [Oboznach] Like '%УД' or [Oboznach] Like '%ЛУ' or [Oboznach] Like '%ТБ' or [Oboznach] Like '%Э3' or [Oboznach] Like '%ПЭ3' or [Oboznach] Like '%Д7' or [Oboznach] Like '%К3' or [Oboznach] Like '%Д4' or [Oboznach] Like '%ДП' or [Oboznach] Like '%РИ' or [Oboznach] Like '%ПГ3' or [Oboznach] Like '%ПГ4' or [Oboznach] Like '%Г4' or [Oboznach] Like '%Э4' or [Oboznach] Like '%ТЭ4' or [Oboznach] Like '%ПИ' or [Oboznach] Like '%И2')"
    rst.Open Ask, conn, adOpenStatic, adLockBatchOptimistic  ' выполняем запрос.
    arr1 = rst.GetRows 'закидываем в массив
    conn.Close 'закрываем соединение
    arr1 = TransposeDim(arr1) 'переворачиваем массив из строк в столбец через функцию TransposeDim с сайта майкрософт
    For i = LBound(arr1) To UBound(arr1)
        For j = LBound(arr2) To UBound(arr2)
            If Len(arr2(j, 1)) > 0 Then
                If InStr(1, arr1(i, 0), "СБ") > 0 Then
                    If InStr(arr2(j, 1), "-") > 0 Then
                        m = Left(arr2(j, 1), InStr(1, arr2(j, 1), "-") - 1) + "СБ"
                        If InStr(1, arr2(j, 1) + "СБ", arr1(i, 0), vbTextCompare) > 0 Then
                            If CInt(arr1(i, 2)) = CInt(arr1(i, 3)) Then 'cравниваем числовые значения
                                arr2(j, 2) = arr1(i, 0)
                            Else
                                arr2(j, 2) = "нет страниц"
                            End If
                        Else
                            If InStr(1, m, arr1(i, 0), vbTextCompare) > 0 Then
                                If CInt(arr1(i, 2)) = CInt(arr1(i, 3)) Then 'cравниваем числовые значения
                                    arr2(j, 2) = arr1(i, 0)
                                Else
                                    arr2(j, 2) = "нет страниц"
                                End If
                            End If
                        End If
                    Else
                        If InStr(1, arr2(j, 1) + "СБ", arr1(i, 0), vbTextCompare) > 0 Then
                            If CInt(arr1(i, 2)) = CInt(arr1(i, 3)) Then 'cравниваем числовые значения
                                arr2(j, 2) = arr1(i, 0)
                            Else
                                arr2(j, 2) = "нет страниц"
                            End If
                        End If
                    End If
                Else
                    If arr2(j, 2) = Empty Then
                        If InStr(1, arr2(j, 1), arr1(i, 0), vbTextCompare) > 0 Then
                            For k = 1 To UBound(massoboz)
                                If InStr(arr2(j, 1), massoboz(k, 1)) > 0 Then
                                    arr2(j, 2) = "нет сборочного"
                                    Exit For
                                Else
                                    If CInt(arr1(i, 2)) = CInt(arr1(i, 3)) Then 'cравниваем числовые значения
                                        arr2(j, 2) = arr1(i, 0)
                                    Else
                                        arr2(j, 2) = "нет страниц"
                                    End If
                                End If
                            Next k
                        End If
                    End If
                End If
            End If
        Next j
    Next i
    ActiveSheet.Cells(2, ncolumn).Resize(UBound(arr2), UBound(arr2, 2)) = arr2'вываливаем на лист
    Application.ScreenUpdating = True
End Sub
А то 2 массива: один 69тыс, второй 500тыс сравнивались друг с другом 6 часов, что мягко говоря очень медленно.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
30.11.2017, 16:27
Ответы с готовыми решениями:

Как ускорить работу макроса
Привет всем! Есть файл, там макрос. Макрос вычисляет наилучший доход. Макрос работает 10 минут. Это очень долго. Как ускорить работу...

Можно ли ускорить работу макроса
Здравствуйте!) У меня вот такой вопрос...возможно ли каким то образом ускорить работу макроса? Если на С++ перенести ускорится?

Как можно ускорить работу макроса Excel с большим кол-вом итерационных циклов?
Есть задача, которую решил, но хотел бы ускорить работу. Проблема в том что суть программы пройти по строкам и столбцам в 1 таблице,...

117
 Аватар для blackeangel
19 / 10 / 1
Регистрация: 22.07.2015
Сообщений: 908
30.11.2017, 19:43  [ТС]
Студворк — интернет-сервис помощи студентам
fever brain, это я понял, я про target..

Добавлено через 4 минуты
Потом почему long возвращает функция? Она ж должна возвращать integer, тк позиции элементов массива у нас целые числа.
Или я что то путаю?
0
oh my god
 Аватар для fever brain
1456 / 796 / 161
Регистрация: 05.01.2016
Сообщений: 2,307
Записей в блоге: 8
30.11.2017, 19:45
Пускай тебя не смущает что текстовые выражения тоже можно сравнивать математическими операциями <>=
если массив сортирован как текст то этот метод будет работать правильно а главное быстро

Добавлено через 1 минуту
Цитата Сообщение от blackeangel Посмотреть сообщение
Она ж должна возвращать integer
Это не важно integer тоже числовой тип но ущербнее
0
 Аватар для blackeangel
19 / 10 / 1
Регистрация: 22.07.2015
Сообщений: 908
30.11.2017, 19:49  [ТС]
fever brain, хотелось бы узнать отзыв об этом коде http://excelvba.ru/code/SearchArray
Так же поиск методом половинного деления работает ещё быстрее или так же как вышеприведенный код?
0
30.11.2017, 19:50

Не по теме:

Цитата Сообщение от blackeangel Посмотреть сообщение
Потом почему long возвращает функция? Она ж должна возвращать integer, тк позиции элементов массива у нас целые числа.
Long целее чем Integer :D

0
oh my god
 Аватар для fever brain
1456 / 796 / 161
Регистрация: 05.01.2016
Сообщений: 2,307
Записей в блоге: 8
30.11.2017, 19:55
Цитата Сообщение от blackeangel Посмотреть сообщение
Так же поиск методом половинного деления
Раз его так обозвали значит оно и есть это класическое обозначение этого метода
а я привел самый простой код от этой класики там примерно то-же самое

Хочу еще добавить если все значения в массиве текстовые то аргумент target ставь string
0
 Аватар для blackeangel
19 / 10 / 1
Регистрация: 22.07.2015
Сообщений: 908
30.11.2017, 19:56  [ТС]
fever brain, принцип работы тогда получается, что нам надо делать цикл только по одному массиву(тот что с листа) и его значения засовывать как target, верно? По полученному индексу получить значение из другого массива?
0
oh my god
 Аватар для fever brain
1456 / 796 / 161
Регистрация: 05.01.2016
Сообщений: 2,307
Записей в блоге: 8
30.11.2017, 20:02
да, первый массив просматриваешь последовательно
все другие массивы если они упорядоченны просматривай быстрым поиском

в чем преемущество, число шагов будет гораздо меньше

что такое 69000 элементов это примерно 16 раз нужно сравнить больше-меньше вместо всех 69000 !
0
 Аватар для blackeangel
19 / 10 / 1
Регистрация: 22.07.2015
Сообщений: 908
30.11.2017, 20:09  [ТС]
fever brain, хорошо, а если есть дубли, как себя это будет вести?

Добавлено через 52 секунды
Или не упорядочены массивы
0
oh my god
 Аватар для fever brain
1456 / 796 / 161
Регистрация: 05.01.2016
Сообщений: 2,307
Записей в блоге: 8
30.11.2017, 20:20
Цитата Сообщение от blackeangel Посмотреть сообщение
а если есть дубли, как себя это будет вести?
выдаст тебе индекс этого дубля причем куда пападет при делении, если к примеру 40 дублей ну выдаст тебе 29-й из этих сорока и чего разьве это важно ? слово то найденно

Добавлено через 2 минуты
Цитата Сообщение от blackeangel Посмотреть сообщение
Или не упорядочены массивы
Значит нужно упорядочить я много раз выкладывал сортировку массивов qSort можешь поискать
или ищи метод быстрой сортировки там тоже число шагов сильно меньше тех что обычно используют

Добавлено через 6 минут
Visual Basic
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
Option Explicit
'Option Compare Text 'Без учета регистра
 
Sub Test()
    ReDim a(0 To 5) As String 'Массив должен быть динамическим, так как он будет перестраиваться (удаление дублей)
    
    a(0) = "340x350x110"
    a(1) = "440x340x300"
    a(2) = "340x220x110"
    a(3) = "440x340x300"
    a(4) = "340x300x220"
    a(5) = "500x400x300"
    
    qSort a, 0, UBound(a) ' Быстрая сортировка
    
'    RemoveDouble a 'Удаление дублей
    
    MsgBox Join(a, vbCrLf) 'Вывод (можно вывести еще кудато там)
    
End Sub
 
Sub qSort(Arr, i&, j&)
    '
    'Сортировка скоростной способ (рекурсия)
    
    Dim ii&, jj&, s$, t$: ii = i: jj = j: s = Arr((ii + jj) \ 2)
    Do Until ii > jj: Do While Arr(ii) < s: ii = ii + 1: Loop: Do While Arr(jj) > s: jj = jj - 1: Loop
        If (ii <= jj) Then t = Arr(ii): Arr(ii) = Arr(jj): Arr(jj) = t: ii = ii + 1: jj = jj - 1
    Loop: Do While i < jj: qSort Arr, i, jj: Exit Do: Loop: Do While ii < j: qSort Arr, ii, j: Exit Do: Loop
End Sub
 
Sub RemoveDouble(Arr)
    '
    'Удаление дублей
    '
    Dim i&, j&
 
    For i = 1 To UBound(Arr)
        If Arr(j) <> Arr(i) Then
            j = j + 1: Arr(j) = Arr(i)
        End If
    Next
    ReDim Preserve Arr(j)
    
End Sub
0
 Аватар для blackeangel
19 / 10 / 1
Регистрация: 22.07.2015
Сообщений: 908
30.11.2017, 20:23  [ТС]
fever brain, а этот qSort для двумерного массива?
0
oh my god
 Аватар для fever brain
1456 / 796 / 161
Регистрация: 05.01.2016
Сообщений: 2,307
Записей в блоге: 8
30.11.2017, 20:27
Цитата Сообщение от blackeangel Посмотреть сообщение
а этот qSort для двумерного массива?
Нет
0
 Аватар для blackeangel
19 / 10 / 1
Регистрация: 22.07.2015
Сообщений: 908
30.11.2017, 20:29  [ТС]
fever brain, а мне нужен для двумерного. У меня оба массива двумерные...
0
oh my god
 Аватар для fever brain
1456 / 796 / 161
Регистрация: 05.01.2016
Сообщений: 2,307
Записей в блоге: 8
30.11.2017, 20:38
Двумерный массив состоит из одномерных
например 3x3
это три одномерных с тремя элементами в каждом

Добавлено через 1 минуту
Цитата Сообщение от blackeangel Посмотреть сообщение
а мне нужен для двумерного
И что тебя так напугало ?

Добавлено через 1 минуту
неудобства только в том что запись придется делать такого вида arr(x,y) вместо arr(x)
все остальное также применимо, если с толком подойти к этому делу.
0
 Аватар для blackeangel
19 / 10 / 1
Регистрация: 22.07.2015
Сообщений: 908
30.11.2017, 21:00  [ТС]
fever brain, не напугало ничего, что то я не допираю никак где это править там. Что туплю уже. Потом надо добавить ещё одну входную переменную номер столбца по которому сортировать. Плюс проверку на то что больше максимального кол-ва столбцов и чтоб не меньше минимального. Так же я не помню как получить кол-во во столбцов двумерного массива. Кол-во строк ещё помню(Ubound(mass))
0
oh my god
 Аватар для fever brain
1456 / 796 / 161
Регистрация: 05.01.2016
Сообщений: 2,307
Записей в блоге: 8
30.11.2017, 21:09
Цитата Сообщение от blackeangel Посмотреть сообщение
как получить кол-во во столбцов двумерного массива. Кол-во строк ещё помню(Ubound(mass))
Размерность это называется
получить можно так
Visual Basic
1
2
3
4
5
6
    Dim a(5, 6), x, y
    
    x = UBound(a, 1)
    y = UBound(a, 2)
    
    MsgBox "Размерность X= " & x & vbLf & "Размерность Y= " & y
0
 Аватар для blackeangel
19 / 10 / 1
Регистрация: 22.07.2015
Сообщений: 908
30.11.2017, 21:20  [ТС]
fever brain, точно точно, нашел в записках аналогичную запись. Осталось только переписать под двумерный массив сортировку. Но написанная тут сортировка в одну строку сильно усложняет чтиво.
0
oh my god
 Аватар для fever brain
1456 / 796 / 161
Регистрация: 05.01.2016
Сообщений: 2,307
Записей в блоге: 8
30.11.2017, 21:24
Цитата Сообщение от blackeangel Посмотреть сообщение
сильно усложняет чтиво
да это я сам нагородил можешь распарсить по строчкам для удобного чтения, мне-то оно итак все понятно
я б даже сделал оба метода (сортировка-поиск) под двумерный массив, только не охота
мне для практики этого не надо, понадобилось бы сделал ))
0
 Аватар для blackeangel
19 / 10 / 1
Регистрация: 22.07.2015
Сообщений: 908
30.11.2017, 21:43  [ТС]
fever brain, завтра попробую собрать все в кучу и провести тестовый загон. Отпишусь о результатах.

Добавлено через 15 минут
fever brain, как вот эту строку заточить под двумерный массив?
Visual Basic
1
 s = Arr((ii + jj) \ 2)
0
oh my god
 Аватар для fever brain
1456 / 796 / 161
Регистрация: 05.01.2016
Сообщений: 2,307
Записей в блоге: 8
30.11.2017, 21:50
Цитата Сообщение от blackeangel Посмотреть сообщение
fever brain, как вот эту строку затащить под двумерный массив?
Ты же уходить собирался ?

Вот смотри:
у тебя двумерный массив который состоит из одномерных
упорядочивать нужно последовательно по столбцам или по строкам
Значит нужно в процедуру добавить еще один аргумент назовем его x
qSort array,x,lbound,ubound

Arr(x,(ii + jj) \ 2) иксом будет текущий сортируемый столбец

Добавлено через 1 минуту
но если как ты писал ранее все упорядоченно то с этим можно не париться
0
 Аватар для blackeangel
19 / 10 / 1
Регистрация: 22.07.2015
Сообщений: 908
30.11.2017, 21:55  [ТС]
fever brain, стоп, сортировать надо правильно. То есть двигать всю строку, то есть надо с собой тащить не только в этом столбце значения, но и все остальные что есть в соседних столбцах.

Добавлено через 3 минуты
И правильнее будет тогда
Visual Basic
1
Arr((ii + jj) \ 2,x)
На сколько я помню, столбцы у нас вторая размерность, изменяемая..
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
30.11.2017, 21:55
Помогаю со студенческими работами здесь

Ускорить код макроса
Привет! Пожалуйста подскажите как можно ускорить код одна строяка выполняется 5 секунд, а у меня их чуть больше миллиона, но прикидкам...

Ускорить действие макроса переноса данных на другой лист
Здравствуйте, имеется макрос для переноса данных на другой лист, но когда данных много (например: около 2000 тыс строк) он начинает...

Ускорить работу кода
Привет всем, Столкнулся с такой проблемой, что мне нужно, что бы код находил нужную ячейку и удалял всю строку со смещением вверх...

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

Как прекратить работу макроса?
Кроме goto к метке в конце программы


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Хитросплетение родственных связей пантеона греческих богов.
russiannick 14.05.2026
Однооконник, позволяющий узреть и изучить отдельных героев древней Греции. <!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible". . .
[golang] Угол между стрелками часов
alhaos 12.05.2026
По заданным значениям часа и минуты необходимо определить значение меньшего угла между стрелками аналогового циферблата часов. import "math" func angleClock(hour int, minutes int) float64 { . . .
Debian 13: Установка Lazarus QT5
ВитГо 09.05.2026
Эта инструкция моя компиляция инструкций volvo https:/ / www. cyberforum. ru/ blogs/ 203668/ 10753. html и его же старой инструкции по установке Lazarus с gtk2. . .
Нейросеть на алгоритме "эстафета хвоста" как перспектива.
Hrethgir 06.05.2026
На десерт, когда запущу сервер. Статья тут https:/ / habr. com/ ru/ articles/ 1030914/ . Автор я сам, нейросеть только помогает в вопросах которые мне не известны - не знаю людей которые знали-бы. . .
Асинхронный приём данных из COM-порта
Argus19 01.05.2026
Асинхронный приём данных из COM-порта Купил на aliexpress термопринтер QR701. Он оказался странным. Поключил к Arduino Nano. Был очень удивлён. Наотрез отказывается печатать русские буквы. Чтобы. . .
попытка написать игровой сервер на C++
pyirrlicht 29.04.2026
попытка написать игровой сервер на плюсах с открытым бесконечным миром. возможно получится прикрутить интерпретатор питон для кастомизации игровой логики. что есть на текущий момент:. . .
Контроль уникальности выбранного документа-основания при изменении реквизита
Maks 28.04.2026
Алгоритм из решения ниже разработан на примере нетипового документа "ЗаявкаНаРемонтСпецтехники", разработанного в КА2. Задача: уведомлять пользователя, если указанная заявка (документ-основание). . .
Благородство как наказание
Maks 24.04.2026
У хорошего человека отношения с женщинами всегда складываются трудно. А я человек хороший. Заявляю без тени смущения, потому что гордиться тут нечем. От хорошего человека ждут соответствующего. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru