Здравствуйте! Буду благодарен, если кто-нибудь сможет помочь с одной задачкой. Примерно похожие видел здесь, но уж очень примерно, а для меня - дремучий лес вовсе. Суть: на листе "расчет" расположена своеобразная таблица со значениями. Первый столбец - объект, остальные столбцы - значения этого объекта по датам. На листе "факт" находятся уточненные значения по объектам и по датам, но не по всем объектам, а лишь по некоторым. Необходимо, чтобы макрос производил поиск на листе "факт" по объектам и копировал значения по датам на лист "расчет", заменяя указанные там, при этом окрашивая ячейку с измененным значением на листе "расчет". Данные по другим датам одного объекта при этом должны оставаться неизменными. В приложенном файле все изображено предельно схематично, но данных будет много больше. Заранее спасибо всем ответившим.
Здравствуйте! Буду благодарен, если кто-нибудь сможет помочь с одной задачкой. Примерно похожие видел здесь, но уж очень примерно, а для меня - дремучий лес вовсе. Суть: на листе "расчет" расположена своеобразная таблица со значениями. Первый столбец - объект, остальные столбцы - значения этого объекта по датам. На листе "факт" находятся уточненные значения по объектам и по датам, но не по всем объектам, а лишь по некоторым. Необходимо, чтобы макрос производил поиск на листе "факт" по объектам и копировал значения по датам на лист "расчет", заменяя указанные там, при этом окрашивая ячейку с измененным значением на листе "расчет". Данные по другим датам одного объекта при этом должны оставаться неизменными. В приложенном файле все изображено предельно схематично, но данных будет много больше. Заранее спасибо всем ответившим.ignat
Т.е. надо взять "расчет", проанализировать "факт", и заменить для соответствующих месяцев значения? Покажите пример с реальной структурой таблиц "расчёт" и "факт", ведь у вас явно месяцы обозначаются не как число (3,2011 etc), а фактические данные - не куча столбиков... Кстати, ваша задача решается даже формулами (если правильно построить структуру "факт")
Т.е. надо взять "расчет", проанализировать "факт", и заменить для соответствующих месяцев значения? Покажите пример с реальной структурой таблиц "расчёт" и "факт", ведь у вас явно месяцы обозначаются не как число (3,2011 etc), а фактические данные - не куча столбиков... Кстати, ваша задача решается даже формулами (если правильно построить структуру "факт")AndreTM
Sub ertert() Dim x, i&, j&, s$ x = Sheets("факт").Range("A1").CurrentRegion.Value With CreateObject("Scripting.Dictionary") .CompareMode = 1 For i = 2 To UBound(x) For j = 1 To UBound(x, 2) Step 2 If Len(x(i, j)) Then s = x(i, j) & "~" & x(1, j + 1) If Not .Exists(s) Then .Item(s) = x(i, j + 1) End If Next j Next i With Sheets("расчет").Range("A1").CurrentRegion .Parent.Activate: x = .Value: .Font.Color = vbBlack End With For i = 2 To UBound(x) For j = 2 To UBound(x, 2) If Len(x(i, j)) Then s = x(i, 1) & "~" & x(1, j) If .Exists(s) Then Cells(i, j).Value = .Item(s) Cells(i, j).Font.Color = vbRed End If End If Next j Next i End With End Sub
[/vba]
или такой вариант: [vba]
Код
Sub ertert() Dim x, i&, j&, s$ x = Sheets("факт").Range("A1").CurrentRegion.Value With CreateObject("Scripting.Dictionary") .CompareMode = 1 For i = 2 To UBound(x) For j = 1 To UBound(x, 2) Step 2 If Len(x(i, j)) Then s = x(i, j) & "~" & x(1, j + 1) If Not .Exists(s) Then .Item(s) = x(i, j + 1) End If Next j Next i With Sheets("расчет").Range("A1").CurrentRegion .Parent.Activate: x = .Value: .Font.Color = vbBlack End With For i = 2 To UBound(x) For j = 2 To UBound(x, 2) If Len(x(i, j)) Then s = x(i, 1) & "~" & x(1, j) If .Exists(s) Then Cells(i, j).Value = .Item(s) Cells(i, j).Font.Color = vbRed End If End If Next j Next i End With End Sub
Спасибо огромное, nilem, и AndreTM, Вы мне здорово помогли! Неужели всё так просто?... А я вот смотрю в код и вижу фигу... Гуманитарий, ёлки-палки :), но по Вашим макросам попробую разобраться всё-таки. Тему можно закрывать.
Спасибо огромное, nilem, и AndreTM, Вы мне здорово помогли! Неужели всё так просто?... А я вот смотрю в код и вижу фигу... Гуманитарий, ёлки-палки :), но по Вашим макросам попробую разобраться всё-таки. Тему можно закрывать.ignat
На самом деле, минимализм предложенного кода как раз говорит о том, что всё не так и просто
Николай, например (по своей привычке), предлагает использовать словарь. То есть примерно так: - сначала с листа "факт" собираем словарь для всех имеющихся значений, с ключом "объект~дата"="значение" - затем анализируем все ячейки в "расчет" на предмет совпадения ключа (первый стобец~первая строка) - если есть, то заменяем на значение из словаря (т.е. на факт)
Я предложил немного другой подход: - делаем копию данных (из "расчет") - определяем место поиска объектов (oFR) и дат (oFC) - те самые первый столбец и первая строка - анализируем "факт", отыскивая для каждого измененного значения имеющиеся дата-объект в наших местах поиска, и при обнаружении - заменяем значения По сути, мой подход аналогичен использованию формулы вида ИНДЕКС(... ПОИСКПОЗ()... ПОИСКПОЗ())
На самом деле, минимализм предложенного кода как раз говорит о том, что всё не так и просто
Николай, например (по своей привычке), предлагает использовать словарь. То есть примерно так: - сначала с листа "факт" собираем словарь для всех имеющихся значений, с ключом "объект~дата"="значение" - затем анализируем все ячейки в "расчет" на предмет совпадения ключа (первый стобец~первая строка) - если есть, то заменяем на значение из словаря (т.е. на факт)
Я предложил немного другой подход: - делаем копию данных (из "расчет") - определяем место поиска объектов (oFR) и дат (oFC) - те самые первый столбец и первая строка - анализируем "факт", отыскивая для каждого измененного значения имеющиеся дата-объект в наших местах поиска, и при обнаружении - заменяем значения По сути, мой подход аналогичен использованию формулы вида ИНДЕКС(... ПОИСКПОЗ()... ПОИСКПОЗ()) AndreTM
nilem, мой алгоритм рассчитан всё же на бОльшее количество исходных данных, а не исправлений Ну нет смысла сначала собирать исправления - а затем ещё и проверять весь объем данных (ведь мы уже знаем, где должны быть произведены исправления).
С другой стороны, чтобы не пользовать двойной .Find (хотя встроенные функции достаточно быстры) - можно как раз oFR/oFC сразу изобразить в виде коллекций (или классов с нужными методами), чтобы иметь возможность быстро найти позицию изменяемого элемента. А затем просто пройтись по списку исправлений...
nilem, мой алгоритм рассчитан всё же на бОльшее количество исходных данных, а не исправлений Ну нет смысла сначала собирать исправления - а затем ещё и проверять весь объем данных (ведь мы уже знаем, где должны быть произведены исправления).
С другой стороны, чтобы не пользовать двойной .Find (хотя встроенные функции достаточно быстры) - можно как раз oFR/oFC сразу изобразить в виде коллекций (или классов с нужными методами), чтобы иметь возможность быстро найти позицию изменяемого элемента. А затем просто пройтись по списку исправлений...AndreTM
Да нет же, Андрей, я привел исправленную цитату не для упреков каких-то или критики, например, а просто над собой посмеялся. Ну да, вставляю словарь по любому поводу, хотя есть куча других методов/подходов/решений и пр. Find - замечательный метод, и алгоритм в Вашем коде тоже оч. хороший. Неудачно пошутил. Извиняйте, если что. Больше не буду
Да нет же, Андрей, я привел исправленную цитату не для упреков каких-то или критики, например, а просто над собой посмеялся. Ну да, вставляю словарь по любому поводу, хотя есть куча других методов/подходов/решений и пр. Find - замечательный метод, и алгоритм в Вашем коде тоже оч. хороший. Неудачно пошутил. Извиняйте, если что. Больше не буду nilem