powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft Office [игнор отключен] [закрыт для гостей] / прошу помоши
31 сообщений из 31, показаны все 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
прошу помоши
    #34070479
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.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
iRow = Sheets("Data1").UsedRange.Row + Sheets("Data1").UsedRange.Rows.Count -  1 
For i = j -  1  To  1  Step - 1 
    T1_date = Sheets("Data_F").Cells( 1 , i)
'    Находим требуемую дату на листе "Data1"
    L = "Data1"
    CLM_1 = FindColumn(L, CStr(T1_date))
        
        If CLM_1 <>  0  Then
                Set ws = ActiveWorkbook.Worksheets(L)
                A1 = " "
                A2 =  2 
                While A1 <> ""
'                   диапазон поиска в столбце
                    Set FC1 = ws.Range(Sheets(L).Cells(A2, CLM_1), Sheets(L).Cells(iRow, CLM_1))
'                    Нашли
                    A1 = FC1.End(xlDown).Value
'                        Если то, что нашли - пустое, тогда это конец
                        If A1 = "" Then GoTo metka_K2:
'                    а в какой строке нашли?
                    A2 = FC1.End(xlDown).Row

'                   диапазон поиска в строке
                    Set FR1 = ws.Range(Sheets(L).Cells(A2,  4 ), Sheets(L).Cells(A2, CLM_1 -  2 ))
metka_K1:
'                    Нашли
                    B1 = FR1.End(xlToRight).Value
'                        если встретился 0 - это ошибка - исправить
                        If B1 = "0" Then
                            FR1.End(xlToLeft).Value = ""
                            GoTo metka_K1:
                        End If
'                        Если то, что нашли - пустое,
'                        или колонка найденного не поменялась, тогда значит нашли 0
                        If B1 = "" Or FR1.End(xlToRight).Column = CLM_1 Then
                            B1 = "0"
                        End If
'                    читаем данные
                    B2 = CInt(Sheets("Data_F").Cells( 2 , i))
'                    вычисляем новые
                    B3 = B2 + CInt(A1) - CInt(B1)
'                    записываем новые
                    Sheets("Data_F").Cells( 2 , i) = CStr(B3)
                Wend
                    
        Else
'        Если даты нет - тогда запоминаем 0
            Sheets("Data_F").Cells( 2 , i) =  0 
        End If
metka_K2:

' ...................
' здесь такая - же обработка других листов с похожей структурой
' ...................

next i


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

Буду все же делать циклами - надежнее.

С уважением BETEPON
---------------------------
Ну вот собственно и ВСЕ.
Подпись:Смерть
...
Рейтинг: 0 / 0
прошу помоши
    #34071145
KL (XL)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
beteponВ общем после проверки код пришлось признать неудачным.
поиск функцией End в случае непрерывной последовательности дает только конц последовательности данных - а средину пропускает

Буду все же делать циклами - надежнее.

Ну и зря. Не End "дает только конц последовательности данных в случае непрерывной последовательности", а End(xlDown) . А вот выражение Cells(65536,Col).End(xlUp) делает как раз то, что тебе нужно ;-)

KL
[MVP - Microsoft Excel]
...
Рейтинг: 0 / 0
прошу помоши
    #34075918
betepon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Решение реализовано на 2-х функциях

Код: 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.
45.
46.
47.
48.
49.
Function ColumnAnaliz_1(ByRef SheetsName As String, ByRef ColumnNumber As Long, _
                        ByRef StartDataRow As Integer, ByRef BlokColumnNumber As Integer) As Integer
                        
Dim A1 As String
Dim A2 As Integer

Dim B1 As String

Dim C1 As Integer

Dim iRow As Long

Dim i As Long

rem Определяем конец листа
iRow = Sheets(SheetsName).UsedRange.Row + Sheets(SheetsName).UsedRange.Rows.Count -  1 
rem стартовая строка
i = StartDataRow
rem накопленная сумма
C1 =  0 
Do
    rem смотрим на ячейку
    A1 = Sheets(SheetsName).Cells(i, ColumnNumber)
    rem если не пустая
    If A1 <> "" Then
        rem включаем строчный анализ
        B1 = RowAnaliz_1(SheetsName, i, ColumnNumber, BlokColumnNumber)
        rem и перескакиваем на следующую строку
        i = i +  1 
    Else
        rem Если пустая ищем первую полную
        A1 = Sheets(SheetsName).Cells(i, ColumnNumber).End(xlDown).Value
         rem если не нашли - конец листа достигнут
          If A1 = "" Then Exit Do
        rem запоминаем номер строки, где нашли
        A2 = Sheets(SheetsName).Cells(i, ColumnNumber).End(xlDown).Row
        rem включаем строчный анализ
        B1 = RowAnaliz_1(SheetsName, CLng(A2), ColumnNumber, BlokColumnNumber)
        rem и перескакиваем на следующую строку
        i = A2 +  1 
    End If
rem Производим накопление суммы
    C1 = C1 + CInt(A1) - CInt(B1)
Loop Until A1 = ""
     Rem выдаем результат
    ColumnAnaliz_1 = C1

End Function


Код: 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.
Function RowAnaliz_1(ByRef SheetName As String, ByRef NumberRow As Long, _
                    ByRef StartDataColumn As Long, _
                    ByRef ColumnBlockNumber As Integer) As Integer
    
Dim B1 As String
Dim B2 As Integer
rem значение левого данного
B1 = ""
Do
    rem смотрим на ячейку левее
    B1 = Sheets(SheetName).Cells(NumberRow, StartDataColumn -  1 )
      rem Если пустая ищем первую полную
    If B1 = "" Then
        rem Значение левой ячейки
        B1 = Sheets(SheetName).Cells(NumberRow, StartDataColumn).End(xlToLeft).Value
        rem колонка найденной ячейки
        B2 = Sheets(SheetName).Cells(NumberRow, StartDataColumn).End(xlToLeft).Column
rem        если ничего не найдено или колонка найденной ячейки принадлежит 
rem        диапзону от 1 до ColumnBlockNumber то данные равны 0
        If B1 = "" Or B2 < ColumnBlockNumber Then
            B1 =  0 
        End If
    End If
Loop Until B1 <> ""
rem присваиваем результат
RowAnaliz_1 = B1

End Function

Проверил. Работает.

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

1) Используй длинные и значимые имена переменных. Даже для временных переменных.
2) Проверять пустая ячейка или нет, лучше через IsEmpty(SomeCell). Это даст тебе настоящую пустую ячейку. А просто сравнение SomeCell="" вернет правду если видимый текст в ячейке совпадает с пустой строкой. Например в ячейке есть формула типа: =if(A1=0, "", 1/A1)
...
Рейтинг: 0 / 0
прошу помоши
    #34079084
betepon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Во всех книгах ни одной формулы на листах нет.
Все вычисления выполняются через макросы.

Но ваш совет очень полезен. Я его учту.

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


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