Домашняя страница Undo Do New Save Карта сайта Обратная связь Поиск по форуму
МИР MS EXCEL - Гость.xls

Вход

Регистрация

Напомнить пароль

 

= Мир MS Excel/Копирование по условиям - Мир MS Excel

Старая форма входа
  • Страница 1 из 1
  • 1
Модератор форума: китин, _Boroda_  
Мир MS Excel » Вопросы и решения » Вопросы по VBA » Копирование по условиям (Макросы Sub)
Копирование по условиям
ignat Дата: Четверг, 30.01.2014, 19:33 | Сообщение № 1
Группа: Пользователи
Ранг: Прохожий
Сообщений: 5
Репутация: 0 ±
Замечаний: 0% ±

Excel 2010
Здравствуйте!
Буду благодарен, если кто-нибудь сможет помочь с одной задачкой. Примерно похожие видел здесь, но уж очень примерно, а для меня - дремучий лес вовсе. Суть: на листе "расчет" расположена своеобразная таблица со значениями. Первый столбец - объект, остальные столбцы - значения этого объекта по датам. На листе "факт" находятся уточненные значения по объектам и по датам, но не по всем объектам, а лишь по некоторым. Необходимо, чтобы макрос производил поиск на листе "факт" по объектам и копировал значения по датам на лист "расчет", заменяя указанные там, при этом окрашивая ячейку с измененным значением на листе "расчет". Данные по другим датам одного объекта при этом должны оставаться неизменными. В приложенном файле все изображено предельно схематично, но данных будет много больше. Заранее спасибо всем ответившим.
К сообщению приложен файл: for_example_mak.xlsx (10.6 Kb)


Сообщение отредактировал ignat - Четверг, 30.01.2014, 19:34
 
Ответить
СообщениеЗдравствуйте!
Буду благодарен, если кто-нибудь сможет помочь с одной задачкой. Примерно похожие видел здесь, но уж очень примерно, а для меня - дремучий лес вовсе. Суть: на листе "расчет" расположена своеобразная таблица со значениями. Первый столбец - объект, остальные столбцы - значения этого объекта по датам. На листе "факт" находятся уточненные значения по объектам и по датам, но не по всем объектам, а лишь по некоторым. Необходимо, чтобы макрос производил поиск на листе "факт" по объектам и копировал значения по датам на лист "расчет", заменяя указанные там, при этом окрашивая ячейку с измененным значением на листе "расчет". Данные по другим датам одного объекта при этом должны оставаться неизменными. В приложенном файле все изображено предельно схематично, но данных будет много больше. Заранее спасибо всем ответившим.

Автор - ignat
Дата добавления - 30.01.2014 в 19:33
AndreTM Дата: Четверг, 30.01.2014, 20:45 | Сообщение № 2
Группа: Друзья
Ранг: Старожил
Сообщений: 1762
Репутация: 500 ±
Замечаний: 0% ±

2003 & 2010
Т.е. надо взять "расчет", проанализировать "факт", и заменить для соответствующих месяцев значения?
Покажите пример с реальной структурой таблиц "расчёт" и "факт", ведь у вас явно месяцы обозначаются не как число (3,2011 etc), а фактические данные - не куча столбиков...
Кстати, ваша задача решается даже формулами :) (если правильно построить структуру "факт")


Skype: andre.tm.007
Donate: Qiwi: 9517375010
 
Ответить
СообщениеТ.е. надо взять "расчет", проанализировать "факт", и заменить для соответствующих месяцев значения?
Покажите пример с реальной структурой таблиц "расчёт" и "факт", ведь у вас явно месяцы обозначаются не как число (3,2011 etc), а фактические данные - не куча столбиков...
Кстати, ваша задача решается даже формулами :) (если правильно построить структуру "факт")

Автор - AndreTM
Дата добавления - 30.01.2014 в 20:45
ignat Дата: Четверг, 30.01.2014, 21:01 | Сообщение № 3
Группа: Пользователи
Ранг: Прохожий
Сообщений: 5
Репутация: 0 ±
Замечаний: 0% ±

Excel 2010
Это и есть реальная структура, просто данных всего 2 столбца, вместо 300 на каждом из листов. И обозначение месяцев именно числовое.
 
Ответить
СообщениеЭто и есть реальная структура, просто данных всего 2 столбца, вместо 300 на каждом из листов. И обозначение месяцев именно числовое.

Автор - ignat
Дата добавления - 30.01.2014 в 21:01
AndreTM Дата: Четверг, 30.01.2014, 21:37 | Сообщение № 4
Группа: Друзья
Ранг: Старожил
Сообщений: 1762
Репутация: 500 ±
Замечаний: 0% ±

2003 & 2010
Ну тогда примерно так:
К сообщению приложен файл: 10-8706-1-1.xls (46.5 Kb)


Skype: andre.tm.007
Donate: Qiwi: 9517375010
 
Ответить
СообщениеНу тогда примерно так:

Автор - AndreTM
Дата добавления - 30.01.2014 в 21:37
nilem Дата: Четверг, 30.01.2014, 21:46 | Сообщение № 5
Группа: Авторы
Ранг: Старожил
Сообщений: 1613
Репутация: 563 ±
Замечаний: 0% ±

Excel 2013, 2016
или такой вариант:
[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
[/vba]


Яндекс.Деньги 4100159601573
 
Ответить
Сообщениеили такой вариант:
[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
[/vba]

Автор - nilem
Дата добавления - 30.01.2014 в 21:46
ignat Дата: Пятница, 31.01.2014, 12:15 | Сообщение № 6
Группа: Пользователи
Ранг: Прохожий
Сообщений: 5
Репутация: 0 ±
Замечаний: 0% ±

Excel 2010
Спасибо огромное, nilem, и AndreTM, Вы мне здорово помогли! Неужели всё так просто?... :) А я вот смотрю в код и вижу фигу... Гуманитарий, ёлки-палки :), но по Вашим макросам попробую разобраться всё-таки. Тему можно закрывать.
 
Ответить
СообщениеСпасибо огромное, nilem, и AndreTM, Вы мне здорово помогли! Неужели всё так просто?... :) А я вот смотрю в код и вижу фигу... Гуманитарий, ёлки-палки :), но по Вашим макросам попробую разобраться всё-таки. Тему можно закрывать.

Автор - ignat
Дата добавления - 31.01.2014 в 12:15
AndreTM Дата: Пятница, 31.01.2014, 13:03 | Сообщение № 7
Группа: Друзья
Ранг: Старожил
Сообщений: 1762
Репутация: 500 ±
Замечаний: 0% ±

2003 & 2010
На самом деле, минимализм предложенного кода как раз говорит о том, что всё не так и просто :)

Николай, например (по своей привычке), предлагает использовать словарь. То есть примерно так:
- сначала с листа "факт" собираем словарь для всех имеющихся значений, с ключом "объект~дата"="значение"
- затем анализируем все ячейки в "расчет" на предмет совпадения ключа (первый стобец~первая строка) - если есть, то заменяем на значение из словаря (т.е. на факт)

Я предложил немного другой подход:
- делаем копию данных (из "расчет")
- определяем место поиска объектов (oFR) и дат (oFC) - те самые первый столбец и первая строка
- анализируем "факт", отыскивая для каждого измененного значения имеющиеся дата-объект в наших местах поиска, и при обнаружении - заменяем значения
По сути, мой подход аналогичен использованию формулы вида ИНДЕКС(... ПОИСКПОЗ()... ПОИСКПОЗ()) :)


Skype: andre.tm.007
Donate: Qiwi: 9517375010
 
Ответить
СообщениеНа самом деле, минимализм предложенного кода как раз говорит о том, что всё не так и просто :)

Николай, например (по своей привычке), предлагает использовать словарь. То есть примерно так:
- сначала с листа "факт" собираем словарь для всех имеющихся значений, с ключом "объект~дата"="значение"
- затем анализируем все ячейки в "расчет" на предмет совпадения ключа (первый стобец~первая строка) - если есть, то заменяем на значение из словаря (т.е. на факт)

Я предложил немного другой подход:
- делаем копию данных (из "расчет")
- определяем место поиска объектов (oFR) и дат (oFC) - те самые первый столбец и первая строка
- анализируем "факт", отыскивая для каждого измененного значения имеющиеся дата-объект в наших местах поиска, и при обнаружении - заменяем значения
По сути, мой подход аналогичен использованию формулы вида ИНДЕКС(... ПОИСКПОЗ()... ПОИСКПОЗ()) :)

Автор - AndreTM
Дата добавления - 31.01.2014 в 13:03
nilem Дата: Пятница, 31.01.2014, 14:36 | Сообщение № 8
Группа: Авторы
Ранг: Старожил
Сообщений: 1613
Репутация: 563 ±
Замечаний: 0% ±

Excel 2013, 2016
[offtop]
... Николай, например (по своей старой фронтовой привычке), предлагает использовать словарь.

:)[/offtop]


Яндекс.Деньги 4100159601573

Сообщение отредактировал nilem - Пятница, 31.01.2014, 14:36
 
Ответить
Сообщение[offtop]
... Николай, например (по своей старой фронтовой привычке), предлагает использовать словарь.

:)[/offtop]

Автор - nilem
Дата добавления - 31.01.2014 в 14:36
AndreTM Дата: Пятница, 31.01.2014, 15:10 | Сообщение № 9
Группа: Друзья
Ранг: Старожил
Сообщений: 1762
Репутация: 500 ±
Замечаний: 0% ±

2003 & 2010
nilem, мой алгоритм рассчитан всё же на бОльшее количество исходных данных, а не исправлений :)
Ну нет смысла сначала собирать исправления - а затем ещё и проверять весь объем данных (ведь мы уже знаем, где должны быть произведены исправления).

С другой стороны, чтобы не пользовать двойной .Find (хотя встроенные функции достаточно быстры) - можно как раз oFR/oFC сразу изобразить в виде коллекций (или классов с нужными методами), чтобы иметь возможность быстро найти позицию изменяемого элемента. А затем просто пройтись по списку исправлений...


Skype: andre.tm.007
Donate: Qiwi: 9517375010
 
Ответить
Сообщениеnilem, мой алгоритм рассчитан всё же на бОльшее количество исходных данных, а не исправлений :)
Ну нет смысла сначала собирать исправления - а затем ещё и проверять весь объем данных (ведь мы уже знаем, где должны быть произведены исправления).

С другой стороны, чтобы не пользовать двойной .Find (хотя встроенные функции достаточно быстры) - можно как раз oFR/oFC сразу изобразить в виде коллекций (или классов с нужными методами), чтобы иметь возможность быстро найти позицию изменяемого элемента. А затем просто пройтись по списку исправлений...

Автор - AndreTM
Дата добавления - 31.01.2014 в 15:10
nilem Дата: Пятница, 31.01.2014, 15:39 | Сообщение № 10
Группа: Авторы
Ранг: Старожил
Сообщений: 1613
Репутация: 563 ±
Замечаний: 0% ±

Excel 2013, 2016
Да нет же, Андрей, я привел исправленную цитату не для упреков каких-то или критики, например, а просто над собой посмеялся. Ну да, вставляю словарь по любому поводу, хотя есть куча других методов/подходов/решений и пр.
Find - замечательный метод, и алгоритм в Вашем коде тоже оч. хороший.
Неудачно пошутил. Извиняйте, если что.
Больше не буду :)


Яндекс.Деньги 4100159601573
 
Ответить
СообщениеДа нет же, Андрей, я привел исправленную цитату не для упреков каких-то или критики, например, а просто над собой посмеялся. Ну да, вставляю словарь по любому поводу, хотя есть куча других методов/подходов/решений и пр.
Find - замечательный метод, и алгоритм в Вашем коде тоже оч. хороший.
Неудачно пошутил. Извиняйте, если что.
Больше не буду :)

Автор - nilem
Дата добавления - 31.01.2014 в 15:39
Мир MS Excel » Вопросы и решения » Вопросы по VBA » Копирование по условиям (Макросы Sub)
  • Страница 1 из 1
  • 1
Поиск:

Яндекс.Метрика Яндекс цитирования
© 2010-2024 · Дизайн: MichaelCH · Хостинг от uCoz · При использовании материалов сайта, ссылка на www.excelworld.ru обязательна!