Добрый день. Прошу вас помочь написать макрос, который сравнивает значения в в ячейках построчно (начиная со второй строки и до конца вниз) в столбцах с 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"));"")
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'а, и попросил макрос...
Цитата
Egor M. написал: спасибо, но мне нужен именно макрос, который будет срабатывать на событие в листе в столбцах F:K.
вот и получилось у меня ТО ЖЕ САМОЕ (видимо, не совсем то - но работает по-своему - хотя, наверно, Target не очень указан - пока в задумчивости)
Скрытый текст
в модуль Листа
Код
Private Sub Worksheet_Change(ByVal Target As Range)
Dim Rng As Range, RN As Range, lr&, m As Range, min As Double, max As Range
With ActiveSheet
lr = .Cells(.Rows.Count, "F").End(xlUp).Row
End With
min = 100 ' исходя из данных любое большое число
Set Rng = ActiveSheet.Range("F2:K" & lr)
If Not Rng Is Nothing Then
Rng.Interior.ColorIndex = xlNone
For Each RN In Rng
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
m.Interior.ColorIndex = 6
End If
End Sub
МОРАЛЬ: ветку вести аккуратно, головой отвечать за каждое слово, ТЗ описывать последовательно (!), не ссылаясь на файл, который ещё не открыли и среди кучи цифр не выискивали не то - что бы хотелось ТСу!? переписывать не буду (Target поправить бы - но только, когда пойму как)... МВТ ответил за всех (похоже, внимательно читал название ветки), чем я иногда грешу, читая описание проблемы... написанное удалять уже жаль - посему запихнула под спойлер (до лучших времён)
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
Вобщем-то вы почти все и сделали, что ТС имел ввиду (не знаю только Тэ эС или ТиСи - я не в тренде). МВТ спасибо, Ваш макрос работает почти как надо - делает все , только красит в УФ, а хотелось бы ПвМ. Макрос JeyCi не сработал. Наверное из-за непоправленного Target. Если таргет это тот диапазон, на изменения в котором макрос начинает заводиться, то тогда Target это от F2 до K-последняя строка. Пожалуйста, подправьте макрос. Я хочу его, т.к. он идет сразу в листик. Спасибо.
Egor M. написал: мне нужен именно макрос, который будет срабатывать на событие в листе
а у Вас Событие Изменения на Листе произошло? чтобы так заявлять... т е войдите в любую ячейку и нажмите Enter... подсветит значение по формуле от vikttur
Цитата
Egor M. написал: сравнивает значения в в ячейках - построчно (начиная со второй строки и до конца вниз) в столбцах с F по K и находит минимальное значение. Найденное значение покрасить в найденной ячейке
может вам вообще не то событие надо и надо ли вообще?..
Цитата
Egor M. написал: Пожалуйста, подправьте макрос. Я хочу его, т.к. он идет сразу в листик
а УФ находится сразу в Excel... зачем мне работать за разработчиков Microsoft? - если они уже организовали все удобства по вопросу - надо брать и пользоваться - Excel'ем... я просто сторонница оптимальности решений, а не соревнований с Microsoft 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 кода...
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
Прошу прощения, но я совершенно не хотел отнять Ваше время. Просто на входе в форум написано, что каждый входящий сюда может рассчитывать на помощь форумчан на добровольной основе. Соответственно я посчитал, что тоже могу сюда войти, и если кто-то захочет, то поможет мне в моем вопросе, а то и в просьбе. А теперь получается, что Вы себе в напряг написали столько текста, решили за мой вопрос свою задачу как Вам было удобнее. А люди, которым несложно было сделать то, что я просил, подумают что вопрос решен и пройдут мимо моей темы. А вопрос-то в две строчки...
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. а чем Вас все-таки не устраивает УФ - просто любопытно?
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
Согласие есть продукт при полном непротивлении сторон
Я, похоже, то-же подумал/понял как 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) и у меня теперь все работает, как я и просил. Считаю, что задача решена. Большое вам всем спасибо. ТС (Егор М.)
Предложу еще один вариант. Вообще без циклов. В модуль листа:
Код
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
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., что Вам мешало в стартовом сообщении указать что изменение ячеек происходит копи-пастом, причем оптом? З.Ы. ТС - Топик Стартер.
Помешало отсутствие кругозора. Я считал, что если есть на свете копи-паст, то руками заносить данные никто не станет. Ошибался. А ТС оказалось вовсе не обидно, как могло показаться в начале.
Обязательно сегодня вечером проверю все новые макросы.
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
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: все-равно ругается на строчку: addr = Range("F"& J & ":K"& J).Find(s).Address. Я подумал, что может это из-за строчки : n = Range("D2").End(xlDown).Row. Я исправил на подсчет строк по столбцу "A", но это не помогло.