Страницы: 1
RSS
Обновление диапазона данными из другой книги
 
Большая просьба помочь с написанием макроса.
Есть постоянно обновляемый диапазон (A4:C1003) в книге 1 и аналогичный диапазон (A5:C1004) в книге 2. Треть строк диапазонов пока пустые. Количество строк можно и не ограничивать, если это не повлияет на время работы макроса.
Столбец С содержит уникальные (неповторяющиеся) текстовые значения.
В книге 2 нужен макрос, который сравнивает столбцы С и если в книге 1 появилось новое значение, дописывает значения А:С в первую пустую строку (по столбцу С) книги 2, а если в книге 1 отсутствует какое-то значение С из книги 2, то вся эта строка (A:IV) в книге 2 очищается.
Если в проверяемой ячейке книги 1 содержится фрагмент "ааа", "ббб" или "ввв", то эта строка в книгу 2 не дописывается.
Если в проверяемой ячейке книги 2 содержится фрагмент "ггг", "ддд" или "еее", то эта строка в книге 2 не очищается.

Очищение всего диапазона в книге 2 и копирование его из книги 1 не подходит, так как в книге 2 есть другие значения в строке, которые относятся к уникальному значению С.
Файлы прилагаются. Для удобства выделил желтым значения, отсутствующие в другой книге и розовым исключения.
Заранее благодарен за любую помощь.
 
Уточнение: Excel 2003.
Неужели даже частичного решения нет?  Хотя бы без исключений. Поиском вроде все перерыл на форуме. Более сложные темы есть, но именно этого не нашел.
Я понимаю, что для профи это слишком просто и не интересно, но я только пользователь. Помогите, пожалуйста.
Жаль ikki нет... По таким мелочам я форум не засорял, обращался к нему..
 
Доброе время суток
Цитата
KSR написал:
Неужели даже частичного решения нет?
Скорее просто не интересно, плюс, выходные.
Цитата
KSR написал:
По таким мелочам я форум не засорял
Если вы способны оценить легкость задачи, то почему не решаете её сами?
 
Цитата
Андрей VG написал:
Если вы способны оценить легкость задачи, то почему не решаете её сами?
А почему Вы решили, что это форум исключительно для профи и нельзя задавать вопросы обычным пользователям?
Я честно пишу, что не знаю, как решить. Кто-то тоже честно не знает и не отвечает. У кого-то просто нет времени, если это для него "мелочь". Кто-то знает, но считает, выше своего достоинства помогать кому-то. И тоже молчит. А кто-то не знает, но либо тратит время на оправдания, либо обвиняет во всем просящего помочь... Просьба до этого не опускаться.
Оценить сложность не могу, но варианта всего два: либо задача сложная и решить можно только за плату - тогда проблем нет: я не жмот и готов заплатить, Такое в другом разделе уже было и претензий ко мне не было. Либо задача простая, но тогда нормальные профи могли бы обидеться, если бы я сразу разместил задачу в соответствующей ветке. Так сложная или простая?
В любом случае спасибо даже за такой ответ.
Изменено: KSR - 16.07.2018 01:12:38
 
Цитата
В книге 2 нужен макрос, который сравнивает столбцы С и если в книге 1 появилось новое значение, дописывает значения А:С в первую пустую строку (по столбцу С) книги 2
Попробуйте разобраться с этой частью, макрос запускать при активном листе1 Книги2. (Обе книги д.б. открыты)
Код
Sub test()
Dim dicObj As Object
Dim i&, iLastRow&
Dim Kniga1_List1 As Worksheet
  Set Kniga1_List1 = Workbooks("Книга1.xls").Worksheets("Лист1")
  Set dicObj = CreateObject("scripting.dictionary")
      dicObj.comparemode = 1
With Sheets("Лист1")
  For i = 5 To .Cells(.Rows.Count, "C").End(xlUp).Row
    dicObj.Item(.Cells(i, "C").Value) = 0
  Next i
End With
With Kniga1_List1
   For i = 4 To .Cells(.Rows.Count, "C").End(xlUp).Row
     If Not dicObj.exists(.Cells(i, "C").Value) Then 'если нет слова, то добавляем его в словарь
            dicObj.Item(.Cells(i, "C").Value) = 0
         iLastRow = Cells(Rows.Count, 1).End(xlUp).Row + 1
         .Range("A" & i & ":C" & i).Copy Cells(iLastRow, 1)
      End If
   Next i
End With
End Sub
 
Kuzmich, большое спасибо!
Первая часть - добавление строчек, которых нет, работает. Это самое главное. С остальным попробую помучиться сам.
 
Прошу прощения, но просьба все-таки помочь. Не получается разобраться со всем.
1. Можно ли использовать этот код с закрытой Книгой1?
При простом копировании диапазонов всегда просто добавляю открытие и закрытие книги. Но в этом коде Книга исправно открывается и закрывается, а код не срабатывает. Данные не вставляются.
Код
Sub test()
Dim dicObj As Object
Dim i&, iLastRow&
Dim Kniga1_List1 As Worksheet

Set Kniga1_List1 = Workbooks.Open("Книга1.xls").Worksheets("Лист1")  'Open добавлено мной
Set dicObj = CreateObject("scripting.dictionary")
dicObj.comparemode = 1
With Sheets("Лист1")
For i = 5 To .Cells(.Rows.Count, "C").End(xlUp).Row
dicObj.Item(.Cells(i, "C").Value) = 0
Next i
End With
With Kniga1_List1
For i = 4 To .Cells(.Rows.Count, "C").End(xlUp).Row
If Not dicObj.exists(.Cells(i, "C").Value) Then 'если нет слова, то добавляем его в словарь
dicObj.Item(.Cells(i, "C").Value) = 0
iLastRow = Cells(Rows.Count, 1).End(xlUp).Row + 1
.Range("A" & i & ":C" & i).Copy Cells(iLastRow, 1)
End If
Next i
End With
Workbooks("Книга1.xls").Close False 'добавлено мной
End Sub
2. Как вставлять только значения без форматов? Мои махинации с PasteSpecial успехом не увенчались.

3. Очищение строк с ненужными словами работает без проблем, но что делать, если искать не слово целиком, а фрагмент?
Код
Sub ClearStr()
Dim lngI As Long

    ClearWord = "ааа, ббб, ввв"
    
For lngI = Cells(Rows.Count, 3).End(xlUp).Row To 5 Step -1 
     If InStr(ClearWord, Cells(lngI, 3)) > 0 Then Rows(lngI).ClearContents
Next lngI
End Sub

Заранее благодарен за любые ответы.
 
Цитата
Код
Option Explicit
'запускаем при активном листе1 Книги2
Sub test()
Dim dicObj As Object
Dim i&, iLastRow&
Dim Kniga1_List1 As Worksheet
Dim FoundCell As Range
  Set Kniga1_List1 = Workbooks("Книга1.xls").Worksheets("Лист1")
  Set dicObj = CreateObject("scripting.dictionary")
      dicObj.comparemode = 1
With Sheets("Лист1") 'Книга2
      'собираем в словарь уникальные текстовые значения из столбца С
  For i = 5 To .Cells(.Rows.Count, "C").End(xlUp).Row
    dicObj.Item(.Cells(i, "C").Value) = 0
  Next i
End With
With Kniga1_List1
   For i = 4 To .Cells(.Rows.Count, "C").End(xlUp).Row      'цикл по Книге1 столбец С
     If Not dicObj.exists(.Cells(i, "C").Value) Then 'если нет слова в словаре, то добавляем его
            dicObj.Item(.Cells(i, "C").Value) = 0
       'Если в проверяемой ячейке книги 1 содержится фрагмент "ааа", "ббб" или "ввв",
       'то эта строка в книгу 2 не дописывается
       If InStr(1, .Cells(i, "C").Value, "ааа") > 0 Or _
          InStr(1, .Cells(i, "C").Value, "ббб") > 0 Or _
          InStr(1, .Cells(i, "C").Value, "ввв") > 0 Then
       Else
         iLastRow = Cells(Rows.Count, 1).End(xlUp).Row + 1  'пустая строка в конце таблицы
         .Range("A" & i & ":C" & i).Copy Cells(iLastRow, 1) 'копируем A:C из Книга1
       End If
     Else      'есть слово в словаре, то очищаем из Книги2 всю строку (A:IV)
       'Если в проверяемой ячейке книги 2 содержится фрагмент "ггг", "ддд" или "еее",
       'то эта строка в книге 2 не очищается
       Set FoundCell = Columns("C").Find(.Cells(i, "C").Value, , xlValues, xlWhole)
         If InStr(1, Cells(FoundCell.Row, "C").Value, "ггг") > 0 Or _
            InStr(1, Cells(FoundCell.Row, "C").Value, "ддд") > 0 Or _
            InStr(1, Cells(FoundCell.Row, "C").Value, "еее") > 0 Then
         Else
            Rows(FoundCell.Row).ClearContents
         End If
     End If
   Next i
End With
End Sub
 
Kuzmich, зачем это? Ссылки на сообщение недостаточно?
 
Kuzmich, большое спасибо! Особенно за подробные комментарии.
При закрытой Книге1 макрос не срабатывает, ругается на строчку 8. При открытой строчки с указанными фрагментами не очищаются, а наоборот, - удаляются из Книги2 все строки со значениями, которые есть в Книге1. Вставляются, как и в прошлый раз не только значения, но и форматы,
Правой рукой через левое ухо я, с Вашим первым кодом еще 3 дня назад задачу решил: открыл вспомогательный Лист2 (разумеется, все книги и листы имеют у меня другие имена), копирую туда значения (точнее постоянно обновляю диапазон) из закрытой Книги1 в том формате, который мне нужен,  а потом Вашим кодом переношу отсутствующие строки на Лист1, удаляю оттуда ненужные строки и кое-что изменяю известными мне кодами. Но и макрос работает не так быстро, как хотелось бы, да и лист дополнительный, хоть и скрытый... Короче, своим способом я недоволен. Но без Вашего первого кода я и его бы не сделал.

vikttur, не смогли бы Вы мне дать ссылку, которую имеете ввиду? Попробую почитать эту ветку, наверняка найду полезное.
 
Цитата
KSR написал:
При открытой строчки с указанными фрагментами не очищаются
Эту проблему исправил благодаря подробным комментариям.
 
Цитата
Kuzmich написал:
есть слово в словаре, то очищаем из Книги2 всю строку (A:IV)
Должно быть наоборот:
Цитата
KSR написал:
если в книге 1 отсутствует какое-то значение С из книги 2, то вся эта строка (A:IV) в книге 2 очищается
Это тоже исправил сам.
Остались проблемы: работа с закрытой книгой и вставка только значений.
Изменено: KSR - 19.07.2018 09:39:59
 
Цитата
вставка только значений.
Код
         .Range("A" & i & ":C" & i).Copy
         Cells(iLastRow, 1).PasteSpecial xlPasteValues
Для ускорения выполнения кода используйте в начале кода
Код
Application.ScreenUpdating = False
и в конце
Код
Application.ScreenUpdating = True

Для открытия первой книги используйте диалог выбора файла

Код
Application.FileDialog(msoFileDialogFilePicker)

 
Kuzmich, еще раз спасибо!
Cells(iLastRow, 1).PasteSpecial xlPasteValues пробовал, но не переносил на другую строку. Теперь работает.
Включение и выключение обновления экрана использую в реальном коде. Тут упрощенный.
А вот куда вставить диалог выбора файла, не врубаюсь, к сожалению.
 
Цитата
А вот куда вставить диалог выбора файла
В начало кода вставляете диалог выбора файла, выбираете файл, берете из него нужные данные, закрываете файл.
Код
    ' диалог выбора файла 
Dim FD As FileDialog
Dim iFileName As String
Dim iShortFileName As String
Set FD = Application.FileDialog(msoFileDialogFilePicker)
    With FD
        .Filters.Clear  'удаляет предопределенные фильтры
        .Filters.Add "Microsoft Excel files", "*.xls"
        .Filters.Add "All files", "*.*"
        .AllowMultiSelect = False
        .InitialFileName = ThisWorkbook.Path
        .Title = "Выберите нужный файл "
        .ButtonName = "Открыть"
        If .Show = False Then
            MsgBox "Вы не указали нужный файл!", 48, "Ошибка"
            Exit Sub
        Else
            iFileName = .SelectedItems(1)
            iShortFileName = Right(.SelectedItems(1), Len(.SelectedItems(1)) _
                        - InStrRev(.SelectedItems(1), "\"))
        End If
    End With
    Set FD = Nothing
       'открываем книгу в режиме только чтение
      Workbooks.Open Filename:=iFileName, UpdateLinks:=False, ReadOnly:=True

      '........
      Workbooks(iShortFileName).Close SaveChanges:=False '(True)
 
Как я понимаю, через диалог Книга1 автоматом не открывается. Получается, что быстрее все-таки делать своим способом - созданием вспомогательного листа, но с использованием Вашего кода, разумеется.
Большущее спасибо, Kuzmich!
 
Цитата
через диалог Книга1 автоматом не открывается
Если вы знаете полный путь к файлу Книга1, то и открывайте сразу
Код
Workbooks.Open Filename:="Полный путь\Книга1.xls", UpdateLinks:=False, ReadOnly:=True
В конце кода не забудьте закрыть файл
Код
Workbooks("Книга1.xls").Close SaveChanges:=False '(True)
 
Цитата
Kuzmich написал:
Если вы знаете полный путь к файлу Книга1, то и открывайте сразу
Спасибо! Так я и открывал сразу. И закрывал в конце (сообщение с кодом #7).
Цитата
KSR написал:
При простом копировании диапазонов всегда просто добавляю открытие и закрытие книги. Но в этом коде Книга исправно открывается и закрывается, а код не срабатывает. Данные не вставляются.
Поменял на Ваш код (он немного другой) - та же ситуация. Книга открывается и закрывается, но вставки данных нет.
Полный путь до файла известен. Это файл базы данных и он никогда не перемещается.
Изменено: KSR - 19.07.2018 15:37:03
 
Цитата
Книга открывается и закрывается, но вставки данных нет.
Открываемая книга (Книга1) становится активной, а в коде активной была Книга 2
 
Цитата
Kuzmich написал:
Открываемая книга (Книга1) становится активной, а в коде активной была Книга 2
Похоже на то. Но тогда получается непонятка: если делаю активной Книгу1, то не срабатывает код словаря. Если делаю активной Книгу2, то не открывается Книга1.
Может поставить
Код
Workbooks.Open Filename:="Полный путь\Книга1.xls", UpdateLinks:=False, ReadOnly:=True
Set Kniga1_List1 = Workbooks("Книга1.xls").Worksheets("Лист1")
перед
Код
With Kniga1_List1
?
Изменено: KSR - 19.07.2018 15:59:07
 
После открытия Книга1 активируйте Книгу2
 
Получилось :)
Спасибо!!!
Изменено: KSR - 19.07.2018 16:10:50
Страницы: 1
Наверх