powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft Office [игнор отключен] [закрыт для гостей] / прошу помоши
25 сообщений из 31, страница 1 из 2
прошу помоши
    #34063128
betepon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть полностью рабочий кода. Но работает медленно, но уверенно. Прошу подсказки - как сделать быстрее.

Код: plaintext
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.
Sub Find_to_index(list As String, index As String, val1 As String, N_horz_val1 As Integer, N_vert_val1 As Integer)
Rem зная имя листа, индекс обьекта и содержимое переменной находим обьект в его координатах
Rem возвращаем номер столбца и номер строки, содержащие обьект

Dim iRow As Integer
Dim iClm As Integer
Dim i As Integer

Узнаем номер последней строки листа
iRow = Sheets(list).UsedRange.Row + Sheets(list).UsedRange.Rows.Count -  1 
Узнаем номер последней колонки листа
iClm = Sheets(list).UsedRange.Column + Sheets(list).UsedRange.Columns.Count -  1 

rem Индекс - это имя колонки, содержащееся в первой строке.
rem Ищем совпадение  данных в первой строке с образцом
For i =  1  To iClm+ 1 
    If Sheets(list).Cells( 1 , i) = index Then GoTo Lab1 rem Нашли
Next i
Lab1:

N_horz_val1 = i
    
    If N_horz_val1 = iClm+ 1  Then
        MsgBox "На листе " + list + " не обнаружен индекс " + index
        GoTo Lab3
    End If

rem Зная колонку ищем теперь столбец
For i =  1  To iRow +  1 
    If Sheets(list).Cells(i, N_horz_val1) = val1 Then GoTo Lab2 rem нашли
Next i
Lab2:

N_vert_val1 = i

    If N_vert_val1 = iRow +  1  Then
        MsgBox "Запись " + val1 + " с индексом " + index + " не найдена на листе " + list
        GoTo Lab3
    End If

Lab3:
    

End Sub

Таким образом входящие - имя листа, индекс колонки и значение переменной. Исходящие - координаты ячейки.

Колонки могут меняться местами по этому различаю колонки по индексам, т.е. по содержимому первой строки колонки.


С уважением BETEPON
---------------------------
Ну вот собственно и ВСЕ.
Подпись:Смерть
...
Рейтинг: 0 / 0
прошу помоши
    #34063175
Фотография talgat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сначала я бы впихнул всю таблицу в массив нужной размерности, а потом
обрабатывал. Получится порядка в 300 раз быстрее будет выполнятся код.


Рыба ищет-где глубже, человек-где больше рыбы.
...
Рейтинг: 0 / 0
прошу помоши
    #34063205
vkodor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
используй Find вместо пробега по колонкам и строкам
...
Рейтинг: 0 / 0
прошу помоши
    #34063336
vbapro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не обижайся, замечания не только по ускорению:
1. для того чтоб было ясно все-таки, что делает функция, объясни, что "такое индекс объекта", "переменная" и т.д.
2. используй with Sheets(list) ... end with
3. вместо GoTo Lab1 , в частности лучше exit for . также и остальные goto нужно убрать. читать будет легче.
4. действительно, как написал vkodor , используй find (хотя это может случиться и медленнее, но попробовать стоит)
5. зачем iRow = Sheets(list).UsedRange.Row + Sheets(list).UsedRange.Rows.Count - 1 , а потом For i = 1 To iRow + 1 - лишнии операции.
...
Рейтинг: 0 / 0
прошу помоши
    #34063412
Фотография k-nike
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А еще у вас комментарии про колонки и столбцы перепутаны. Непонятно.

...
Рейтинг: 0 / 0
прошу помоши
    #34063519
vkodor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vbapro
4. действительно, как написал vkodor , используй find (хотя это может случиться и медленнее, но попробовать стоит)

практика показывает что через Find быстрее
интересно посмотреть случае когда медленей
...
Рейтинг: 0 / 0
прошу помоши
    #34063655
vbapro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vkodor vbapro
4. действительно, как написал vkodor , используй find (хотя это может случиться и медленнее, но попробовать стоит)

практика показывает что через Find быстрее
интересно посмотреть случае когда медленей
писал одно, думал другое :), find быстре, примера обратного у меня нет
...
Рейтинг: 0 / 0
прошу помоши
    #34064692
betepon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
To vkodor
vkodorиспользуй Find вместо пробега по колонкам и строкам
Я бы с радостью, но что - то у меня не получается. То-ли параметры не так задаю, то-ли что-то еще.
Может есть какой примерчик (я не смог использовать тот, что в хелпе)

To vbapro
vbapro"индекс объекта" - если прочитать коментарии немного дальше, то становится ясно, - индекс это любой текст, находящийся в первой ячейке данной колонки. Поскольку места колонок могут меняться, то нужно (без задания именованых масивов) узнавать где-какая колонка.
vbapro"переменная" - набор букв и цифр, который может принимать любое значение в заданных типом переменной пределах. В данном конкретном случае это то значение, которое содержит объект.
vbapro"Объект"-в данном конкретном случае - ячейка на листе

Итого - задача (написано в самом низу в первом посте) зная лист, значение первой ячейки в столбце и значение, которое находится внутри ячейки узнать абсолютные координаты ячейки, а именно номер столбца и номер строки.

vbaproиспользуй with Sheets(list) ... end with
Хорошо. А дает ли это ускорение или какие-то другие преимущества кроме более структурированного листинга?

По поводу вашего пункта 3 - учту и сделаю

По поводу пункта 4 смотрите выше

По поводу пункта 5, действительно - лишняя операция. Не заметил.

To k-nike
k-nikeА еще у вас комментарии про колонки и столбцы перепутаны. Непонятно.

Вместо
авторrem Зная колонку ищем теперь столбец
Читать
Код: plaintext
rem Зная колонку ищем теперь строку

To All
У меня есть пример, когда осуществляется поиск данных, и потом работа с ними, но примера с поиском данных, а потом получением координат этих данных на листе у меня нет.
...
Рейтинг: 0 / 0
прошу помоши
    #34064796
betepon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Попробовал следующую конструкцию (по вашим образцам) для поиска текста в первой строке листа и определения его координат.


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
With Sheets(list)
Rem Количество колонок на листе +1
    iClm = .UsedRange.Column + .UsedRange.Columns.Count
End With
    
Rem В области от первой колонки до последней и в первой строке 
With Worksheets(list).Range(Sheets(list).Cells( 1 ,  1 ), Sheets(list).Cells( 1 , iClm -  1 ))
Rem Ищем  содержимое переменной index и узнаем адрес ячейки
    Set C = .Find(index, LookIn:=xlValues)
Rem и узнаем адрес ячейки
    firstAddress = C.Address
End With


Все великолепно. Запускается, но находит "Empty" хотя данные точно есть.
Та процедура, что была описана в начале поста великолепно их находит

С уважением BETEPON
---------------------------
Ну вот собственно и ВСЕ.
Подпись:Смерть
...
Рейтинг: 0 / 0
прошу помоши
    #34064815
betepon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
To talgat

talgatСначала я бы впихнул всю таблицу в массив нужной размерности, а потом обрабатывал. Получится порядка в 300 раз быстрее будет выполнятся код.

Да-аа. Хочу посмотреть на массив во весь лист Excel, при том что листы всегда разные, и на листе до 600 столбцов и до 5000 строк. (бывают больше, бывают меньше).
И это только для того, чтобы найти координаты ОДНОЙ ячейки на листе ?

Быстрее процедура работать не станет, а вот медленнее точно. При том что на листе могут быть ка цифровые так и текстовые данные.

С уважением BETEPON
---------------------------
Ну вот собственно и ВСЕ.
Подпись:Смерть
...
Рейтинг: 0 / 0
прошу помоши
    #34064923
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vbaproНе обижайся, замечания не только по ускорению:
1. для того чтоб было ясно все-таки, что делает функция, объясни, что "такое индекс объекта", "переменная" и т.д.Это не надо объяснять. Надо имена переменным давать осмысленные. Не index, а IndexOfColumn или IndexOfValueInsideColumn. Писать чуть-чуть дольше, разбираться на порядок проще и ошибок меньше.

vbapro2. используй with Sheets(list) ... end with Наоборот, не стоит это использовать. Когда в одном макросе много работаешь с With потом фиг поймешь к какому из объектов относится данная строка, приходится постоянно бегать вверх-вниз по тексту к with чтобы понять от чего мы собственно говоря берем with. А уж если начнешь делать вложеные with - получается такая каша...

vbapro3. вместо GoTo Lab1 , в частности лучше exit for . также и остальные goto нужно убрать. читать будет легче.С этим согласен.

vbapro4. действительно, как написал vkodor , используй find (хотя это может случиться и медленнее, но попробовать стоит)Стоит, стоит. Получится быстрее точно.

vbapro5. зачем iRow = Sheets(list).UsedRange.Row + Sheets(list).UsedRange.Rows.Count - 1 , а потом For i = 1 To iRow + 1 - лишнии операции.Ну циклы там вообще не нужны....


2betepon:
6. Если возвращаешь из процедуры значение через параметр - всегда указывай его явно ByRef.
7. Если нужно чего-то возвращать лучше делать функцию а не процедуру.
8. Использовать MsgBox внутри процедуры не очень хорошо. Если ты попытаешься искать несколько значений в цикле через свою процедуру, то на каждый чих пользователю прийдется нажимать кнопку. Лучше возвращать текст или объект, а потом при нужде либо показывать его на экран сразу через MsgBox или склеить несколько текстов от разных запусков процедуры и показать их все разом.

На, развлекайся:
Код: plaintext
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.
Option Explicit

Function FindValueInColumn(ByVal SheetName As String, ByVal ColumnName As String, ByVal SearchValue As Variant, _
        ByRef FoundRow As Integer, ByRef FoundColumn As Integer) As String
    Dim ws As Worksheet
    Dim rColumn As Range
    
    FoundRow =  0 
    FoundColumn =  0 
    
    On Error GoTo NoSuchSheet
    Set ws = ActiveWorkbook.Worksheets(SheetName)
    
    On Error GoTo ColumnNotFound
    Set rColumn = ws.UsedRange.Rows( 1 ).Find(ColumnName).EntireColumn
    FoundColumn = rColumn.Column
    
    On Error GoTo ValueNotFound
    FoundRow = rColumn.Find(SearchValue).Row

    FindValueInColumn = "Ok"
    Exit Function
    
NoSuchSheet:
    FindValueInColumn = "Active Workbook doesn't have sheet with name " & SheetName
    Exit Function
ColumnNotFound:
    FindValueInColumn = "Can not find column with name " & ColumnName
    Exit Function
ValueNotFound:
    FindValueInColumn = "Can not find value " & SearchValue & " in column " & ColumnName
    Exit Function
End Function

Sub test()
    Dim e As String, x As Integer, y As Integer
    e = FindValueInColumn("Sheet1", "ggg", "asd", y, x)
    If e = "Ok" Then
        MsgBox ("Found value in cell with coordinates: " & y & ":" & x)
    Else
        MsgBox ("Search failed with error: " & e)
    End If
End Sub
...
Рейтинг: 0 / 0
прошу помоши
    #34065148
vbapro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
если уж пошел разбор фрагмента чуть шире, чем просили :), то в процедуре есть еще подводный камень - индекс строк Integer. нужно всегда для строк делать Long без раздумий: память не экономится, а размера типа может нехватить
...
Рейтинг: 0 / 0
прошу помоши
    #34065553
betepon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вроде разобрался - все не так сложно. Но есть вопрос по строке

Код: plaintext
Set rColumn = ws.UsedRange.Rows( 1 ).Find(ColumnName).EntireColumn

Хочу разобраться.
Я так понял что в этой строке создается Range из одной строки с номером 1, в котором производится поиск ColumnName.
А зачем EntireColumn, и что оно такое.

С уважением BETEPON
---------------------------
Ну вот собственно и ВСЕ.
Подпись:Смерть
...
Рейтинг: 0 / 0
прошу помоши
    #34065654
betepon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вроде разобрался - как оно работает - решил проверить.

Ваш пример колонку не обнаруживает, хотя точно известно, что она есть.


С уважением BETEPON
---------------------------
Ну вот собственно и ВСЕ.
Подпись:Смерть
...
Рейтинг: 0 / 0
прошу помоши
    #34065678
betepon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Нет - все нормально. Разобрался - все работет. Ошибся при подгонке макроса к программе.


С уважением BETEPON
---------------------------
Ну вот собственно и ВСЕ.
Подпись:Смерть
...
Рейтинг: 0 / 0
прошу помоши
    #34065682
betepon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вопрос по

Код: plaintext
Set rColumn = ws.UsedRange.Rows( 1 ).Find(ColumnName).EntireColumn

не отменяю. (хочу научится)

С уважением BETEPON
---------------------------
Ну вот собственно и ВСЕ.
Подпись:Смерть
...
Рейтинг: 0 / 0
прошу помоши
    #34065708
vkodor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
т. к. rColumn обьявлен как range
EntireColumn - возвращает столбец
т.е. допустим ColumnName найдено в столбце "D" диапозона ws.UsedRange.Rows(1).
следовательно rColumn = ws.Range("D:D")
...
Рейтинг: 0 / 0
прошу помоши
    #34066383
betepon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ага. Спасибо. Теперь понял.

Огромное спасибо всем откликнувшимся. Стало работать заметно быстрее.

С уважением BETEPON
---------------------------
Ну вот собственно и ВСЕ.
Подпись:Смерть
...
Рейтинг: 0 / 0
прошу помоши
    #34067869
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
beteponВроде разобрался - все не так сложно. Но есть вопрос по строке
Код: plaintext
Set rColumn = ws.UsedRange.Rows( 1 ).Find(ColumnName).EntireColumn
Хочу разобраться.
Я так понял что в этой строке создается Range из одной строки с номером 1, в котором производится поиск ColumnName.
А зачем EntireColumn, и что оно такое.
Вопрос "что оно такое" надо смотреть во встроенном хелпе. Там все четко и ясно написано. Запускаешь VBA, нажимаешь F1 и ищешь непонятное слово.

А вообще, пойми одну простую вещь - любой Range это множество. И как любое множество, ты можешь разбить на маленькие множества, так и любой Range, ты можешь разбить на маленькие Range. При этом адресация ячеек внутри Range всегда соответсвет самому Range от которого берется, а не листу!
В данном случае:
UsedRange дает тебе область на листе в которой есть данные.
UsedRange.Rows(1) даст тебе первую строку области в которой есть данные. Причем это не полная строка! Если у тебя UsedRange имеет адрес относительно листа C3:F10, то UsedRange.Rows(1) даст область с адресом относительно листа C3:F3.
UsedRange.Rows(1).Find(ColumnName) - даст одну (первую) ячейку в области первая строка, занятого диапазона.
EntireColumn - (как и братский метод EntireRow) в отличие от методов Rows, Columns, Cells и Range возвращают область относительно листа а не Range от которого берутся. Поэтому UsedRange.Rows(1).Find(ColumnName).EntireColumn даст полную колонку листа.

В принципе, чтобы не заставлять эксель искать в пустых ячейках до и после реально заполненых. Можно после:
Set rColumn = ws.UsedRange.Rows(1).Find(ColumnName).EntireColumn
добавить еще одну строку
Set rColumn = Intersect(ws.UsedRange, rColumn)
Тогда rColumn вместо области D:D станет описывать область D3:D10 и поиск значения ускорится еще чуть-чуть. Заодно, если ищешь пустую ячейку, то получишь пустую ячейку внутри таблицы с данными, а не первую ячейку колонки.
...
Рейтинг: 0 / 0
прошу помоши
    #34068689
betepon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А как в Find можно управлять направлением поиска.
Например мне надо узнать значение первой не пустой ячейки слева от текущей. т.е.
Есть лист. На нем много строк и много столбцов.
В первой ячейке каждого столбца находится дата.
задача следующая -
1. определить все даты, которые входят в промежуток -30 дней от текущей (это я сделал)
2. За дату перебрать все строки в этой колонке до конца листа. Если встретилась не пустая ячейка, тогда в этой строке ищем первое число левее текущего. Если нашли - вычитаем его из текущего. Полученную разницу суммируем с разницей по предидущей строке (если она была)
Таким образом к концу листа накапливаем сумму всех разниц.

Проблема в следующем
1. Строк много - хотелось бы игнорировать пустые строки (в данный моммент действую полным перебором)
2. быстрее находить первое число левее текущего, либо приходить к выводу, что его нет (т.е. оно равно 0)

Первую задачу я почти решил методом Find - по аналогии с предидущей.
А вот как заставить find искать в обратную сторону (справа на лево) и не конкретное значение, а первое не пустое (игнорируя при этом значения нулевые, если таковые встретятся.)


С уважением BETEPON
---------------------------
Ну вот собственно и ВСЕ.
Подпись:Смерть
...
Рейтинг: 0 / 0
прошу помоши
    #34068820
vkodor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
Cells.Find(What:="ïàïà", After:=Range("E23"), LookIn:=xlFormulas, LookAt _
        :=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
        False).Activate

After:=Range("E23") - отвечает за начало поиска

SearchOrder:=, SearchDirection:=

SearchOrder:=xlByRows, SearchDirection:=xlNext - двигаться в право потом вниз
SearchOrder:=xlByColumns, SearchDirection:=xlNext двигаться в вниз потом право
SearchOrder:=xlByRows, SearchDirection:=xlPrevious двигаться в влево потом вверх
SearchOrder:=xlByColumns, SearchDirection:=xlPrevious двигаться в вверх потом влево



а еще есть функция End
для нахождения первой пустой ячейки очень хорошо подходит
...
Рейтинг: 0 / 0
прошу помоши
    #34069294
betepon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А как найти первую не пустую ? Not End?

С уважением BETEPON
---------------------------
Ну вот собственно и ВСЕ.
Подпись:Смерть
...
Рейтинг: 0 / 0
прошу помоши
    #34069418
vkodor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Поиск последней ячейки в Excel
...
Рейтинг: 0 / 0
прошу помоши
    #34070307
betepon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Все. Сам разобрался. Там было просто.

А поиск последней ячейки мне не нужен. Но за ссылку спасибо. Воспользуюсь.

Допишу и покажу, что получилось.

С уважением BETEPON
---------------------------
Ну вот собственно и ВСЕ.
Подпись:Смерть
...
Рейтинг: 0 / 0
прошу помоши
    #34070401
vkodor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
beteponДопишу и покажу, что получилось.

С уважением BETEPON


жду с нетерпением
...
Рейтинг: 0 / 0
25 сообщений из 31, страница 1 из 2
Форумы / Microsoft Office [игнор отключен] [закрыт для гостей] / прошу помоши
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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