Страницы: 1
RSS
"Обозначить" границы поиска, где нужно искать, чтобы был верный результат.
 
Добрый день!
Благодаря помощи с форума имею следующий код. (файл во вложении)
Так же в папке журналы 2 журнала для теста

Ранее всегда искал через If cl.Value Like "ЧТО НУЖНО НАЙТИ" Then
Но вот сейчас немного задачка такая, что так, боюсь, не получится

Мне нужно искать не во всем журнале, а только в области "самого журнала" (где №, ФИО детей и оценки)
Проверка_1: Если у ребенка < 3 оценок за четверть. Четверти всегда обозначены в журнале в столбце так: Итог. 2 четв. (ну или Итог. 3 четв. и .т.д.) То выделить красным (это уже есть в коде cl.Interior.ColorIndex = 3)
Проверка_2 Если в какой-либо день < 3 оценок. То есть проверить только области дат. Они, слава богу всегда в строке 14 (к слову, где и информация об Итог. 2. четв.

Как проверить клетки мне уже подсказали: If IsEmpty(cl.Offset(, 1)) And IsEmpty(cl.Offset(, 2)) And IsEmpty(cl.Offset(, 3)) - проверяем пусто ли в ячейке вправее.

Но я не знаю как "обозначить" границы поиска где мне нужно искать чтобы был верный результат. Подскажите пожалуйста с моей проблемой.
 
extrafant написал
Цитата
нужно искать не во всем журнале, а только в области "самого журнала" (где №, ФИО детей и оценки)
Область поиска в коде у вас определяется строкой кода с UsedRange.SpecialCells(2).Cells
Код
For Each cl In iWb.Worksheets(1).UsedRange.SpecialCells(2).Cells 
Вам надо определить диапазон
"самого журнала" (где №, ФИО детей и оценки)
Вставьте в код
Код
Dim FoundFIO As Range
Dim Diapazon As Range
Dim iLastRow As Long

Перед строкой с UsedRange
Код
Set FoundFIO = Columns(2).Find("Фамилия", , xlValues, xlWhole)
      iLastRow = FoundFIO.Offset(1).End(xlDown).Row
     set  Diapazon = Range(Cells(FoundFIO.Row + 1, "A"), Cells(iLastRow, "DB"))
и замените UsedRange на Diapazon
Изменено: Kuzmich - 19.08.2017 09:57:40
 
Цитата
Kuzmich написал:
и замените UsedRange на Diapazon
Я заменил в коде все UsedRange на Diapazon. Перестало создавать файлы и в "отчет" перестало писать ФИО учителя и прочую инфу. Я так понял, что заменять это нужно только в той проверке (а не во всем коде) которая мне нужна для журнала
А если у меня журнал не закончится на "DB" или не дойдит к строке с надписью DB? (в сентябре, к примеру, если проверить)
  Diapazon = Range(Cells(FoundFIO.Row + 1, "A"), Cells(iLastRow, "DB"))

Можно к чему-то другому "прицепить" окончание?
А можно вот так If cl.Value Like "$*$" найти "Ф.И.", а потом проверять ячейки на наличие пустот. Но опять же где окончание журнала? Он ведь "Динамичный"

Может к числам даты прицепиться? Пока они есть есть и журнал? Но я не знаю как это сделать((, подскажите пожалуйста?
Изменено: extrafant - 18.08.2017 13:29:40
 
Цитата
А если у меня журнал не закончится на "DB" или не дойдит к строке с надписью DB?
Тогда надо определять последний столбец , я так полагаю, это будет столбец с "Итого за год"
Код
Dim iLastColumn As Integer   

  Set FoundFIO = Columns(2).Find("Фамилия", , xlValues, xlWhole)
      iLastRow = FoundFIO.Offset(1).End(xlDown).Row
      iLastColumn = Cells(FoundFIO.Row, Columns.Count).End(xlToLeft).Column
      Set Diapazon = Range(Cells(FoundFIO.Row + 1, "A"), Cells(iLastRow, iLastColumn))
Изменено: Kuzmich - 19.08.2017 09:58:22
 
Цитата
Перестало создавать файлы и в "отчет" перестало писать ФИО учителя и прочую инфу
Где идет цикл перебора из массива измените строку (хотя зачем поиск по UsedRange, когда все эти строки в столбце А)
Код
            Set cl = iWb.Worksheets(1).UsedRange.Find(arrFind(I), , xlValues, xlPart)
Изменено: Kuzmich - 18.08.2017 14:01:54
 
Цитата
Kuzmich написал:
я так полагаю, это будет столбец с "Итого за год"
Нет, это будет столбец с последний датой. Например, приспичит проверить журнал, скажем, 15 сн. Значит 15 и будет последней датой

Подправил. Теперь перестало считать то, что ранее считало и в журнальных файлах ничего не отмечает ((
Последний файл с проблемами во вложении
Изменено: extrafant - 18.08.2017 14:28:50
 
Цитата
это будет столбец с последний датой
Так вычтете 2 из iLastColumn (столбец с Итог за год)
 
Цитата
Kuzmich написал:
Так вычтете 2 из iLastColumn (столбец с Итог за год)
Столбца Итог за год вообще может не быть, если проверка проводится, скажем 18 сентября. Последняя дата будет 18
Пожалуйста, посмотрите мою предыдущую запись. Я все вставил в код, но не работает (
 
Измените код
Код
      Set Diapazon = Range(Cells(FoundFIO.Row + 1, "A"), Cells(iLastRow, iLastColumn))
          
    'For Each cl In iWb.Worksheets(1).Diapazon.SpecialCells(2).Cells
    For Each cl In Diapazon.SpecialCells(2).Cells
 
Пробовал. Вот весь код с последними изменениями. Так же ничего не работает. Может я что-то не очень внимательно изменил?
Код
Option Explicit
Sub CheckingLog()
Dim arrFind()
Dim sFolder$, sFiles$, sumH&, I&, iFilename$, iStr$
Dim iWb  As Workbook
Dim cl As Range
Dim FreeCells As Integer
Dim sumFreeCells As Integer
Dim FoundFIO As Range
Dim Diapazon As Range
Dim iLastRow As Long
Dim iLastColumn As Integer
On Error Resume Next

arrFind = Array("Учитель:", "Предмет:", "Класс:", "Период:", "Учебный год:")
With Application.FileDialog(msoFileDialogFolderPicker)
    If .Show = False Then Exit Sub
    sFolder = .SelectedItems(1)
End With
sFolder = sFolder & IIf(Right(sFolder, 1) = Application.PathSeparator, "", Application.PathSeparator)
Application.ScreenUpdating = False
sFiles = Dir(sFolder & "*.xls*")
Do While sFiles <> ""
    Set iWb = Workbooks.Open(sFolder & sFiles)
    sumH = 0: sumFreeCells = 0: iFilename = Empty
          
          Set Diapazon = Range(Cells(FoundFIO.Row + 1, "A"), Cells(iLastRow, iLastColumn))
          
          Set FoundFIO = Columns(2).Find("Фамилия", , xlValues, xlWhole)
      iLastRow = FoundFIO.Offset(1).End(xlDown).Row
      iLastColumn = Cells(FoundFIO.Row, Columns.Count).End(xlToLeft).Column
      Diapazon = Range(Cells(FoundFIO.Row + 1, "A"), Cells(iLastRow, iLastColumn))
          
          
    'For Each cl In iWb.Worksheets(1).Diapazon.SpecialCells(2).Cells
        For Each cl In Diapazon.SpecialCells(2).Cells
            If cl.Value Like "2 Н" Or cl.Value Like "3 Н" Or cl.Value Like "4 Н" Or cl.Value Like "5 Н" Then
            sumH = sumH + 1
            cl.Interior.ColorIndex = 3
            cl.AddComment
            cl.Comment.Text Text:="" & vbCrLf & "оценка+Н"
        End If
            
       'Здесь проверка на 2+ 3 свободных ячейки
        If cl.Value Like "2" Then
        If IsEmpty(cl.Offset(, 1)) And IsEmpty(cl.Offset(, 2)) And IsEmpty(cl.Offset(, 3)) Then
           
            sumFreeCells = sumFreeCells + 1
            cl.Interior.ColorIndex = 3
            cl.AddComment
            cl.Comment.Text Text:="" & vbCrLf & "После двойки прошло более трех уроков без оценки"
        End If
        End If
      'Здесь проверка на 2+ 3 свободных ячейки
      
      
            
    Next
    
    With ThisWorkbook.Worksheets("отчет")
        .Range("F" & .Cells(.Rows.Count, "F").End(xlUp).Row + 1) = sumH
        .Range("G" & .Cells(.Rows.Count, "G").End(xlUp).Row + 1) = sumFreeCells
        
        For I = 0 To UBound(arrFind)
            Set cl = iWb.Worksheets(1).UsedRange.Find(arrFind(I), , xlValues, xlPart)
            If Not cl Is Nothing Then
iStr = Trim(Mid(cl.Value, WorksheetFunction.Search(":", cl.Value) + 1))
                .Cells(.Cells(.Rows.Count, I + 1).End(xlUp).Row + 1, I + 1) = iStr
                If I <= 2 Then
                    If iFilename <> Empty Then
                    iFilename = iFilename & " " & iStr
                    Else
                    iFilename = iStr
            End If
        End If
      End If
        Next
End With
iWb.SaveAs Filename:="" & iFilename & ".xlsx", FileFormat:=xlOpenXMLWorkbook
iWb.Close False
sFiles = Dir
Loop
Application.ScreenUpdating = True
End Sub

 
Первое, что в глаза бросилось
Set FoundFIO... должно быть присвоено ДО Set Diapazon...
И вообще, на будущее. Строку On Error Resume Next добавляйте в код в самую последнюю очередь. Когда и без нее код работает без ошибок и как Вам нужно. Это для случаев, когда ошибка не является запланированной. Как раз Ваш случай

P/S/ Не по теме. А чем Вас не устроил вариант с ...Like "*#*Н*"..? Зачем заменили на эту длинную цепочку с ...Or...? Мне так, для общего развития
Изменено: Sanja - 18.08.2017 16:40:45
Согласие есть продукт при полном непротивлении сторон
 
Цитата
Sanja написал: ...чем Вас не устроил вариант с ...Like "*#*Н*"..? Зачем заменили на эту длинную цепочку с ...Or...?
Привет! Спасибо тебе огромное, что помогаешь мне в этом макросе с моей проблемой! Не поверишь, один раз совпало, что в теме урока так символы совпали: №7 Н. (что-то там уже не помню) и оно выделило. Пришлось отказаться и вернуться к длинному коду.
Поменял местами. Все работает

Но я по прежнему не докумекал как мне начать считать (смысл моего поста)
Здесь вариант с Like подойдет?

Вот что ищу:
Если у ребенка < 3 оценок за четверть. Четверти всегда обозначены в журнале в столбце так: Итог. 2 четв. (ну или Итог. 3 четв. и .т.д.) То выделить красным (это уже есть в коде cl.Interior.ColorIndex = 3)
Проверка_2 Если в какой-либо день < 3 оценок. То есть проверить только области дат. Они, слава богу всегда в строке 14 (к слову, где и информация об Итог. 2. четв.

Еще вот проблема (сложность) что журнал-то может начать не четвертью, а скажем 26 числом ( вообще любым)
Изменено: extrafant - 19.08.2017 14:20:49
 
Цитата
extrafant написал: так символы совпали: №7 Н
Можно просто удалить первую звездочку: ..Like "#*Н*"... Но вопрос не по теме...
Согласие есть продукт при полном непротивлении сторон
 
Цитата
Sanja написал:
Можно просто удалить первую звездочку: ..Like "#*Н*"... Но вопрос не по теме...
Пусть пока что так будет! Оптимизировать буду уже когда будет что-то здесь понятно
 
Досконально не тестировал...
Скрытый текст
Согласие есть продукт при полном непротивлении сторон
 
Вот в этой строке я бы заменил UsedRange на Columns(1)
Код
            Set cl = iWb.Worksheets(1).UsedRange.Find(arrFind(I), , xlValues, xlPart)
 
Завтра буду с утра экспериментировать. Код еще не тестил даже. А это изменение существенно будет влиять?
 
Я вам уже писал, что зачем искать по всему диапазону UsedRange, если у вас искомые данные в столбце А
 
Цитата
Kuzmich написал:
Я вам уже писал, что зачем искать по всему диапазону UsedRange, если у вас искомые данные в столбце А
Я понял. Влияет на скорость работы
 
Добавил

Dim lRow as Integer - код стал запускаться
Поменял  If IsEmpty(cl.Offset(, 1).Resize(, 3)) Then на  If IsEmpty(cl.Offset(, 1)) And IsEmpty(cl.Offset(, 2)) And IsEmpty(cl.Offset(, 3)) Then стало видеть Если 2 и пустые клетки

2Kuzmich
Почему искомые только в столбце А? У меня искомые данные по всему листу
 
Цитата
Kuzmich написал:
Изменено: Kuzmich  - 19 Авг 2017 09:58:22





Спасибо за правку! Буду править
 
Цитата
Почему искомые только в столбце А? У меня искомые данные по всему листу
Я говорю о данных из этого массива
Код
arrFind = Array("Учитель:", "Предмет:", "Класс:", "Период:", "Учебный год:")
 
Тю...понятно. Я почему-то ошибочно решил, что речь шла о листе с журналом (поэтому я был в недоумении). Тогда все на своих местах. Спасибо!
 
Это про поиск в цикле
Код
 For I = 0 To UBound(arrFind)
            Set cl = iWb.Worksheets(1).UsedRange.Find(arrFind(I), , xlValues, xlPart)
            If Not cl Is Nothing Then
 
extrafant, посмотрите на свои сообщения - зачем Вы постоянно цитируете? А #21 Вам нравится?
 
Понял. Больше не буду цитировать
Страницы: 1
Читают тему
Наверх