Страницы: 1 2 След.
RSS
vba найти минимальное значение в строке, исключая ноль
 
Добрый день.
Прошу вас помочь написать макрос, который сравнивает значения в в ячейках
построчно (начиная со второй строки и до конца вниз) в столбцах с F по K и находит минимальное значение, исключая: 0, пусто, нет данных.
Найденное значение покрасить в найденной ячейке и скопировать его в ячейку в столбце D  соответствующей строки.
Файл-пример прикрепил.
Заранее спасибо.
 
Не макросом принимается?
Формула массива, ввдится Ctrl+Shift+Enter:
=МИН(ЕСЛИ(F2:K38>0;F2:K38))
Обычная, без массивности:
=НАИБОЛЬШИЙ(F2:K38;СЧЁТЕСЛИ(F2:K38;">0"))
Если показать минимальное в нужной строке:
=ЕСЛИ(НАИБОЛЬШИЙ(F2:K2;СЧЁТЕСЛИ(F2:K2;">0"))=НАИБОЛЬШИЙ($F$2:$K$38;СЧЁТЕСЛИ($F$2:$K$38;">0"));НАИБОЛЬШИЙ(F2:K2;СЧЁТЕСЛИ(F2:K2;">0"));"")
 
Vikttur, спасибо, но мне нужен именно макрос, который будет срабатывать на событие в листе в столбцах F:K.
 
Как-то так (а подкрашивание через УФ сделайте)
Код
Sub tt()
Dim L As Long: L = Cells(Rows.Count, 1).End(xlUp).Row
Dim I As Long, J As Integer
Dim arr
For I = 1 To L
arr = Range("F" & I & ":K" & I)
For J = 1 To UBound(arr, 2)
If arr(1, J) <= 0 Then arr(1, J) = Application.WorksheetFunction.Max(arr)
Next J
Cells(I, 4) = Application.WorksheetFunction.Min(arr)
Next I
End Sub

 
Цитата
vikttur написал: =МИН(ЕСЛИ(F2:K38>0;F2:K38))
а я думала, это только я ТАК подумала/поняла...  
:(  а ТС поблагодарил vikttur'а, и попросил макрос...
Цитата
Egor M. написал: спасибо, но мне нужен именно макрос, который будет срабатывать на событие в листе в столбцах F:K.
вот и получилось у меня ТО ЖЕ САМОЕ (видимо, не совсем то -
но работает по-своему - хотя, наверно, Target не очень указан - пока в задумчивости)

Скрытый текст

МОРАЛЬ: ветку вести аккуратно, головой отвечать за каждое слово, ТЗ описывать последовательно (!), не ссылаясь на файл, который ещё не открыли и среди кучи цифр не выискивали не то - что бы хотелось ТСу!? переписывать не буду  8)
(Target поправить бы - но только, когда пойму как)...
МВТ ответил за всех  :)  (похоже, внимательно читал название ветки), чем я иногда грешу, читая описание проблемы... написанное удалять уже жаль - посему запихнула под спойлер (до лучших времён)
Изменено: JeyCi - 11.07.2015 17:32:15
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
JeyCi, осталось дождаться ответа ТС, чтобы понять, что он имел в виду на самом деле  :)
 
Вобщем-то вы почти все и сделали, что ТС имел ввиду (не знаю только Тэ эС или ТиСи - я не в тренде).
МВТ спасибо, Ваш макрос работает почти как надо - делает все , только красит в УФ, а хотелось бы ПвМ.
Макрос JeyCi не сработал. Наверное из-за непоправленного Target. Если таргет это тот диапазон, на изменения в котором  макрос начинает заводиться,
то тогда Target это от F2 до K-последняя строка. Пожалуйста, подправьте макрос. Я хочу его, т.к. он идет сразу в листик.
Спасибо.
 
Цитата
Egor M. написал: Макрос JeyCi не сработал.
он же Private Sub Worksheet_Change
Цитата
Egor M. написал: мне нужен именно макрос, который будет срабатывать на событие в листе
а у Вас Событие Изменения на Листе произошло? чтобы так заявлять... т е войдите в любую ячейку и нажмите Enter... подсветит значение по формуле от vikttur
Цитата
Egor M. написал: сравнивает значения в в ячейках - построчно (начиная со второй строки и до конца вниз) в столбцах с F по K и находит минимальное значение. Найденное значение покрасить в найденной ячейке
может вам вообще не то событие надо и надо ли вообще?..
Цитата
Egor M. написал: Пожалуйста, подправьте макрос. Я хочу его, т.к. он идет сразу в листик
;)  а УФ находится сразу в Excel... зачем мне работать за разработчиков Microsoft? - если они уже организовали все удобства по вопросу - надо брать и пользоваться - Excel'ем... я просто сторонница оптимальности решений, а не соревнований с Microsoft  :oops:
p.s.
Код
Private Sub Worksheet_Change(ByVal Target As Range)
Dim Rng As Range, RN As Range, lr&, m As Range, min As Double
With Application: DisplayAlerts = False: .ScreenUpdating = False: .EnableEvents = False: .Calculation = xlManual: End With
     
    With ActiveSheet
    lr = .Cells(.Rows.Count, "F").End(xlUp).Row
    End With
     
    Set Rng = ActiveSheet.Range("F2:K" & lr)
    If Not Rng Is Nothing Then
    Rng.Interior.ColorIndex = xlNone
    
    For rr = 1 To Rng.Rows.Count + 1
   min = 1000 ' исходя из данных любое большое число
 
        For Each RN In Rng.Rows(rr).Cells
            If (IsNumeric(RN.Value) And RN.Value <> 0 And RN.Value <= min) Then
            min = RN.Value: Set m = RN
            Else: min = min
            End If
        Next RN
        m.Interior.ColorIndex = 6
    Next
    End If
With Application: DisplayAlerts = True: .ScreenUpdating = True: .EnableEvents = True: .Calculation = xlAutomatic: End With
End Sub
переписывать не буду    (т к формулу от vikttur можете сами адаптировать под каждую конкретную строку)... да и вообще без событий, похоже, хотите - чтобы само всё работало (и подправлялось кем-то) - не бывает так - если хотите, чтобы работало так, как надо ! вам - приложите усилия (кроме фразы "я хочу")
P.P.S
просто оптимальное решение - это то, что экономит время для др полезных дел, а не чужими руками творит бог весть знает что  
- но мы с МВТ вроде бы натворили - если соединить наши 2 кода...  ;)
Изменено: JeyCi - 12.07.2015 11:09:15
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
Прошу прощения, но я совершенно не хотел отнять Ваше время. Просто на входе в форум написано,
что каждый входящий сюда может рассчитывать на помощь форумчан на добровольной основе.
Соответственно я посчитал, что тоже могу сюда войти, и если кто-то захочет, то поможет мне в моем вопросе, а то и в просьбе.
А теперь получается, что Вы себе в напряг написали столько текста, решили за мой вопрос свою задачу как Вам было удобнее.
А люди, которым несложно было сделать то, что я просил, подумают что вопрос решен и пройдут мимо моей темы.
А вопрос-то в две строчки...
 
Цитата
Egor M. написал: А теперь получается, что Вы себе в напряг написали столько текста,
вам в помощь
Цитата
Egor M. написал: , решили за мой вопрос свою задачу как Вам было удобнее.
как вопрос поставлен, такая задача и решалась
Цитата
Egor M. написал: каждый входящий сюда может рассчитывать на помощь форумчан на добровольной основе. Соответственно я посчитал, что тоже могу сюда войти, и если кто-то захочет, то поможет мне в моем вопросе, а то и в просьбе.
пошла подмена понятий... в программировании это не проходит
Цитата
Egor M. написал: А вопрос-то в две строчки...
теперь после всего написанного - уже в одну строчку и один нюанс... как из одного макроса выйти в др макрос...
Цитата
Egor M. написал: А люди,..., подумают что вопрос решен и пройдут мимо моей темы.
... вы уверены, что верно рассчитываете?.. программисты Microsoft тоже рассчитывают, что их функционал даст людям больше возможностей для оптимальной автоматизации работы - если в полном объёме использовать те возможности, которые даёт Excel, а не создавать Америку с нуля... и добровольная помощь рассчитывает, что если вы задаёте вопрос - то имеете потенциал или хотя бы приложите усилия, чтобы понять ответ...  

p.s. вам помогли задуматься о возможностях эффективного использования имеющихся ресурсов для разработки наилучшего решения, а вы даже не подумали, что вопрос может быть решён намного лучше, чем вам кажется... вы написали
Цитата
Egor M. написал: Пожалуйста, подправьте макрос. Я хочу его
- вам даже подправили его... хотя место "хотеть" находится ЗДЕСЬ ...  
Цитата
Egor M. написал: Прошу вас помочь написать макрос Найденное значение покрасить в найденной ячейке и скопировать его в ячейку в столбце D  соответствующей строки.
что ещё не сделали за вас? что сделали вы? на добровольной основе  :) - Просто на входе в форум ещё написано,
Цитата
2.7. Если вам нужен не совет по самостоятельному решению задачи, а чтобы все сделали за вас - добро пожаловать в ветку Работа
 
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
Переделал на привязку к событию, оставил без покраски (остаюсь при своем мнении, что через УФ проще и лучше)
Код
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Count > 1 Then Exit Sub
If Intersect(Target, ActiveSheet.UsedRange) Is Nothing Then Exit Sub
Application.EnableEvents = False
Dim I As Long, J As Integer
Dim arr
I = Target.Row
arr = Range("F" & I & ":K" & I)
For J = 1 To UBound(arr, 2)
If arr(1, J) <= 0 Then arr(1, J) = Application.WorksheetFunction.Max(arr)
Next J
Cells(I, 4) = Application.WorksheetFunction.Min(arr)
Application.EnableEvents = True
End Sub

P.S. а чем Вас все-таки не устраивает УФ - просто любопытно?
Изменено: МВТ - 12.07.2015 15:42:10
 
EgorM,могу предложить два макроса,первый макрос решает ваш вопрос,
второй макрос убирает заливку,если это необходимо.
 
Код
Sub search()
Dim s As Double, I&, J&, n&, addr$
  n = Range("D2").End(xlDown).Row
For J = 2 To n
 s = Application.Max(Range("G" & J & ":K" & J))
  For I = 1 To 5
  If Range("G" & J & ":K" & J).Cells(I) < s And Range("G" & J & ":K" & J).Cells(I) <> 0 Then
    s = Range("G" & J & ":K" & J).Cells(I)
  End If
  Next I
   Range("D" & J) = s
   addr = Range("G" & J & ":K" & J).Find(s).Address
   Range(addr).Interior.ColorIndex = 3
Next J
End Sub
Код
Sub test1()
Dim J&, n&
 n = Range("D2").End(xlDown).Row
 For J = 2 To n
  Range("G" & J & ":K" & J).Interior.Color = xlNone
 Next J
End Sub
 
Вариант со словарем.
И покраской ячейки  ;)
Код
Private Sub Worksheet_Change(ByVal Target As Range)
Set arrRange = Range("F2:K" & Cells(Rows.Count, 1).End(xlUp).Row)
If Not Intersect(Target, arrRange) Is Nothing And Target.Count = 1 Then
On Error Resume Next
arrRange.Interior.ColorIndex = xlNone
Set oDict = CreateObject("Scripting.Dictionary")
For Each cl In arrRange.Cells
    If IsNumeric(cl) And cl <> 0 Then
        oDict.Add Item:=cl.Address, Key:=cl.Value
    End If
Next
minVal = Application.WorksheetFunction.min(oDict.Keys)
With Range(oDict.Item(minVal))
    .Interior.ColorIndex = 6
    Cells(.Row, 4) = minVal
End With
End If
End Sub
Согласие есть продукт при полном непротивлении сторон
 
sv2013, а зачем во втором макросе цикл?
 
Добрый вечер,можно ,конечно, без цикла обойтись,во вспомогательном втором макросе.
С уважением ко всем участникам обсуждения.
Код
Sub test2()
Dim n&
 n = Range("D2").End(xlDown).Row
  Range("G2:K" & n).Interior.Color = xlNone
End Sub
 
Я, похоже, то-же подумал/понял как vikttur,  а ТС продолжает интриговать  ;)
Цитата
Egor M. написал: подумают что вопрос решен и пройдут мимо моей темы
так решен вопрос или нет?
на всякий случай вариант "как у всех", но с другой WorksheetFunction
Код
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("F2:K" & Cells(Rows.Count, 1).End(xlUp).Row)) Is Nothing And Target.Count = 1 Then
On Error Resume Next
Application.EnableEvents = False
With Target
    Set arrRow = Range("F" & .Row & ":K" & .Row)
    arrRow.Interior.ColorIndex = xlNone
    For I = 1 To arrRow.Count
        minVal = Application.WorksheetFunction.Small(arrRow, I)
        If minVal <> 0 Then
            Set minCell = arrRow.Find(minVal)
            minCell.Interior.ColorIndex = 6
            Cells(.Row, 4) = minVal
            Exit For
        End If
    Next
End With
Application.EnableEvents = True
End If
End Sub
Согласие есть продукт при полном непротивлении сторон
 
Ничего общего с интригой. Просто столько вариантов дали. Надо ж было потестировать.
Sanja, Ваш симпатичный вариант не заработал, т.е. макрос не реагировал на изменения в ячейках.
         А ,,как у всех,, реагирует на изменения только в одной ячейке, а если вставлять в столбец оптом, молчит.
SV2013 макрос запинается на строчке addr = Range("G" & J & ":K" & J).Find(s).Address . Я его проверял не на файле-примере. а на большом файле.
         Он доходит до первой пустой ячейки и останавливается.
МВТ, в вашем макросе тоже идет реакция только на 1 ячейку, а если вставлять данные оптом, то макрос записывает в ячейку столбца D только данные
       из первой строчки вставленного диапазона. И еще момент: если при первом вычислении в строке макрос и вычисляет и красит, то при втором изменении в той же
       строке макрос перекраской себя уже не утруждает. Вы спрашивали про нелюбовь к УФ - не могу внятно ответить. Как-то УФ не вселяет в меня уверенность, видимо от редкого использования.

В итоге я из каждого макроса понадергал по чуть-чуть (включая макрос от JeyCi) и у меня теперь все работает, как я и просил.
Считаю, что задача решена. Большое вам всем спасибо.
ТС (Егор М.)
 
Цитата
Egor M. написал: Sanja, Ваш симпатичный вариант не заработал, т.е. макрос не реагировал на изменения в ячейках
А Вы куда скопировали код? Подозреваю, что в стандартный модуль, а нужно в модуль листа.
 
Предложу еще один вариант. Вообще без циклов.
В модуль листа:
Код
Private Sub Worksheet_Change(ByVal Target As Range)
    Dim x As Range, y As Range
    If Target.Count > 1 Then Exit Sub
    If Intersect(Target, [F:K]) Is Nothing Then Exit Sub
    Application.EnableEvents = False
    Set x = Intersect(Rows(Target.Row), [F:K])
    x.Interior.ColorIndex = xlNone
    x.Replace 0, "qq", xlWhole
    Set y = x.Find(Application.Min(x.Value))
    If y Is Nothing Then
        Cells(Target.Row, "D") = ""
    Else
        y.Interior.ColorIndex = 3: Cells(y.Row, "D") = y
    End If
    x.Replace "qq", 0, xlWhole
    Application.EnableEvents = True
End Sub
Пример во вложении.
Чем шире угол зрения, тем он тупее.
 
Цитата
Egor M. написал: а если вставлять в столбец оптом, молчит.
Egor M., что Вам мешало в стартовом сообщении указать что изменение ячеек происходит копи-пастом, причем оптом?
З.Ы. ТС - Топик Стартер.
Согласие есть продукт при полном непротивлении сторон
 
Цитата
А Вы куда скопировали код? Подозреваю, что в стандартный модуль, а нужно в модуль листа
Чесслово вставил , куда следовало. В лист, в самую его нежную часть. Сейчас перепроверил - нет, не работает.
 
Egor M,попробуйте на вашем другом файле:
Код
Sub search2()
Dim s As Double, I&, J&, n&, addr$
  n = Range("D2").End(xlDown).Row
For J = 2 To n
 s = Application.Max(Range("G" & J & ":K" & J))
  For I = 1 To 5
  Set x = Range("G" & J & ":K" & J).Cells(I)
  If x.Value < s And x.Value <> 0 And Not IsEmpty(x) Then
    s = x.Value
  End If
  Next I
   Range("D" & J) = s
   addr = Range("G" & J & ":K" & J).Find(s).Address
   Range(addr).Interior.ColorIndex = 3
Next J
End Sub
 
Цитата
Egor M., что Вам мешало в стартовом сообщении указать что изменение ячеек происходит копи-пастом, причем оптом?
З.Ы. ТС - Топик Стартер.
Помешало отсутствие кругозора. Я считал, что если есть на свете копи-паст, то руками заносить данные никто не станет. Ошибался. А ТС оказалось вовсе не обидно, как могло показаться в начале.

Обязательно сегодня вечером проверю все новые макросы.
 
Цитата
sv2013 написал: Application.Max(Range("G" & J & ":K" & J))
- так лучше, чем было у меня... в код поста №8 точно лучше вставить в строку14
Код
min = Application.max(Rng.Cells) 'вместо 1000

p.s. sv2013  :) почему вы вместо F столбца (как заказывал ТС) - по всем кодам заглядываетесь на G столбец?..  
Изменено: JeyCi - 13.07.2015 10:51:15
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
Jeyci,добрый день,с учетом вашей корректировки:
Спасибо за просмотр кода.С уважением.
Код
Sub search3()
Dim s As Double, I&, J&, n&, addr$,x As Range
  n = Range("D2").End(xlDown).Row
For J = 2 To n
 s = Application.Max(Range("F" & J & ":K" & J))
  For I = 1 To 6
  Set x = Range("F" & J & ":K" & J).Cells(I)
  If x.Value < s And x.Value <> 0 And Not IsEmpty(x) Then
    s = x.Value
  End If
  Next I
   Range("D" & J) = s
   addr = Range("F" & J & ":K" & J).Find(s).Address
   Range(addr).Interior.ColorIndex = 3
Next J
End Sub
Код
Sub test2()
Dim n&
 n = Range("D2").End(xlDown).Row
  Range("F2:K" & n).Interior.Color = xlNone
End Sub
Изменено: sv2013 - 13.07.2015 12:30:43
 
SAS888, на копи-пейст макрос перестает трудиться. А если по каждой ячейке пройтись, то все отлично работает. Спасибо.
 
Речь о том, что требуется обрабатывать множество ячеек зашла лишь после того, как я опубликовал свой пример.
Поэтому, при копировании - вставке, макрос обработки события будет немного другой (см. вложение).
Чем шире угол зрения, тем он тупее.
 
sv2013: все-равно ругается на строчку: addr = Range("F" & J & ":K" & J).Find(s).Address.
Я подумал, что может это из-за строчки : n = Range("D2").End(xlDown).Row. Я исправил
на подсчет строк по столбцу "A", но это не помогло.
 
SAS888, Вот теперь самое оно. Благодарю Вас.
 
JeyCi, Ваша добавка пришлась к месту. Стало выглядеть эстетичнее. Спасибо.
Страницы: 1 2 След.
Читают тему
Наверх