Squeak.ru - шаблоны программирования

Как избежать использования .Select и .Activate при создании таблицы?

Мне сказали, что использование .Select и .Workbooks.Activate — не лучший способ написать Vba. Приведенный ниже код, как правило, работает идеально, и, похоже, никаких реальных проблем не возникает. Activeworkbook не является проблемой из-за Workbooks("FUA.XLSM").Activate. Тогда мой вопрос: что было бы хорошей альтернативой/подходом? Извините, если это пустая трата времени или это глупый вопрос, но я слышал, что использование этих методов не является хорошим способом сделать это в долгосрочной перспективе. Я беспокоюсь, что это не сработает или создаст проблемы в будущем. Следует отметить, что без Workbooks("FUA.XLSM"). Activate код имеет тенденцию создавать ошибки, поскольку он путается в выборе рабочей книги. Короче говоря, мой вопрос: как мне избежать использования Select и .Activate, чтобы уменьшить вероятность ошибок в будущем?
Код выглядит следующим образом..

  Dim wb1 As Excel.Workbook
    Dim wb2 As Excel.Workbook
    Set wb2 = Workbooks.Open("C:\Users\Ha.csv")
    Set wb1 = Workbooks("FUA")
   Dim sht1 As Worksheet
   Dim sht2 As Worksheet
  Dim copyRange As Range
  Set sht1 = wb1.Sheets("Sheet1")
   Set sht2 = wb2.Sheets("Ha")
With wb1.Sheets("Sheet1")
   Range("AA3").Select
    If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
        lastRow = .Cells.Find(What:="*", _
                      After:=.Range("AA3"), _
                      Lookat:=xlPart, _
                      LookIn:=xlFormulas, _
                      SearchOrder:=xlByRows, _
                      SearchDirection:=xlPrevious, _
                      MatchCase:=False).row
    Else
        lastRow = 1
    End If
End With
Workbooks("FUA.XLSM").Activate
   Range("AA3").Select
    sht1.ListObjects.Add(xlSrcRange, , xlYes).Name = _
        "Table1"
    Range("Table1[#All]").Select
    sht1.ListObjects("Table1").Range.AutoFilter Field:=9, Criteria1:= _
        ">=-1000000000000", Operator:=xlAnd, Criteria2:="<=1000000000000000"
         Application.DisplayAlerts = False
    Selection.SpecialCells(xlCellTypeVisible).Copy
    Application.DisplayAlerts = True
    Set wb2 = Workbooks.Open("C:\Users\Ha.csv")
          Application.DisplayAlerts = False
wb2.Sheets("Ha").Paste
 wb2.SaveAs Filename:= _
        "C:\Users\Ha.csv", FileFormat:= _
        xlCSV, CreateBackup:=False
        Workbooks("Ha.csv").Close
End Sub 
22.08.2017

  • Большинство .Select/.Activate можно удалить, если я правильно понял. У вас есть свои диапазоны, в основном, указанные. У вас есть один Selection.SpecialCells(xlcellTypeVisible).Copy, который должен быть просто Range("Table1[#All]").SpecialCells.... Попробуйте удалить/закомментировать строки Select/Activate и посмотреть, работает ли он должным образом или нет. 22.08.2017
  • @BruceWayne Спасибо, Бэтмен... эм, Брюс. Если я удалю Range(AA3).Select ниже Workbooks(FUA.XLSM).Activate, а также Range(Table1[#All]).Select, как правило, не работает, поскольку создает таблицу в выбранной ячейке. Если я не укажу это, это сбивает с толку, а также сбивает с толку, какую книгу выбрать, если нет Workbook.Activate, поэтому я немного озадачен, как этого избежать. Однако другой Select можно удалить. 22.08.2017
  • Workbooks("wbk.xlsx").Activate // Range("A1").Select // Selection.Value = 1 можно переписать как Workbooks("wbk.xlsx").Range("A1").Value = 1. 22.08.2017
  • (a) Ваш код выполняет Range("AA3").Select сразу после вашего Workbooks("FUA.XLSM").Activate. Какой лист в FUA.XLSM будет активен в это время (поскольку Range("AA3") будет ссылаться на ячейку AA3 на активном листе)? (b) Ранее (сразу после оператора With wb1.Sheets("Sheet1")) вы выполняете Range("AA3").Select, чтобы выбрать ячейку AA3 активного (и единственного?) листа в Ha.csv. Какова цель этого Select? 22.08.2017
  • @ YowE3K Хороший вопрос. Спасибо за это. От них нет никакой пользы, они спорны. Range(Table1[#All]).Select и Workbooks(FUA.XLSM).Activate по-прежнему необходимо заменить 22.08.2017
  • @BruceWayne Ты был прав, Брюс. Большинство выделений можно удалить. Не уверен, почему я так не думал. Я не совсем уверен, как я могу заменить Workbooks(FUA.XLSM).Activate и Range(Table1[#All]).Select. 22.08.2017
  • Range("Table1[#All]").Select не нужно, если вы используете Range("Table1[#All]").SpecialCells(xlCellTypeVisible).Copy вместо Selection.SpecialCells(xlCellTypeVisible).Copy. (Я не использую таблицы Excel, но не понимаю, почему это не сработает.) И если вы не используете безоговорочное Range, вам не нужно Activate. Насколько я вижу, все остальное кажется квалифицированным. 22.08.2017
  • Вы также должны быть в состоянии избавиться от второго Set wb2 = Workbooks.Open("C:\Users\Ha.csv"). 22.08.2017
  • @ YowE3K Спасибо за ваши предложения. Я протестировал удаление Range(AA3).Select и .Activate далее, и он имеет тенденцию создавать ошибку 1004, но не раньше создания таблицы в той ячейке, где она выделена, поскольку она не ищет правильное место. 22.08.2017

Ответы:


1

Вероятно, проголосовали за то, что сказали это, но если это не сломалось, не чините это. Ваш код уже работает нормально, нет реальной причины его менять, если только он не работает или не появляются ошибки. Похоже, вы уже протестировали его.

Ваш код уже оптимизирован и быстрее, хотя вот альтернатива, чтобы избежать Select. Если вы получите ошибку 1004 с методами выбора, похожими на последнюю строку sht2.Range("A:I").Copy Columns(last_col + 1).PasteSpecial в приведенном ниже коде, она все равно продолжится.

Sub test()

    Dim wb1 As Excel.Workbook
    Set wb1 = Workbooks("XXX.XLSM")                ' from here, use wb1 to refer to fua.xlsm

    Dim wb2 As Excel.Workbook                      ' ditto for wb2
    Set wb2 = Workbooks.Open("C:\Users\Ha.csv")

    Dim sht1 As Worksheet                          ' ditto for sht1
    Set sht1 = wb1.Sheets("Sheet1")

    Dim sht2 As Worksheet
     Set sht2 = wb2.Sheets("Ha")

    If Application.WorksheetFunction.CountA(sht1.Cells) <> 0 Then

        LastRow = sht1.Cells.Find( _
                        What:="*", _
                        After:=sht1.Range("A1"), _
                        Lookat:=xlPart, _
                        LookIn:=xlFormulas, _
                        SearchOrder:=xlByRows, _
                        SearchDirection:=xlPrevious, _
                        MatchCase:=False).row
    Else
        LastRow = 1
    End If




  sht1.ListObjects.Add(xlSrcRange, sht1.Range("A:I"), xlYes).Name = "Table1"





    sht1.ListObjects("Table1").Range.AutoFilter _
                Field:=9, _
                Criteria1:=">=-1000000000000", _
                Operator:=xlAnd, _
                Criteria2:="<=1000000000000000"

    Application.DisplayAlerts = False          ' not sure if needed



      sht1.Range("A:I").SpecialCells(xlCellTypeVisible).Copy

    On Error Resume Next
   sht2.Range("A:I").Copy Columns(last_col + 1).PasteSpecial
    On Error Resume Next
    Application.DisplayAlerts = True           ' not sure if needed

    wb2.Save                                   ' already C:\Users\Ha.csv
    wb2.Close

End Sub
22.08.2017

2

Вот ваш код, переписанный.
Я думаю, что он имеет ту же функциональность.

Sub test()

    Dim wb1 As Excel.Workbook
    Set wb1 = Workbooks("FUA.XLSM")                ' from here, use wb1 to refer to fua.xlsm

    Dim wb2 As Excel.Workbook                      ' ditto for wb2
    Set wb2 = Workbooks.Open("C:\Users\Ha.csv")

    Dim sht1 As Worksheet                          ' ditto for sht1
    Set sht1 = wb1.Sheets("Sheet1")

    If Application.WorksheetFunction.CountA(sht1.Cells) <> 0 Then

        LastRow = sht1.Cells.Find( _
                        What:="*", _
                        After:=sht1.Range("A1"), _
                        Lookat:=xlPart, _
                        LookIn:=xlFormulas, _
                        SearchOrder:=xlByRows, _
                        SearchDirection:=xlPrevious, _
                        MatchCase:=False).Row
    Else
        LastRow = 1
    End If

    sht1.ListObjects.Add(xlSrcRange, sht1.Range("AA3"), xlYes).Name = "Table1"

    sht1.ListObjects("Table1").Range.AutoFilter _
                Field:=9, _
                Criteria1:=">=-1000000000000", _
                Operator:=xlAnd, _
                Criteria2:="<=1000000000000000"

    Application.DisplayAlerts = False          ' not sure if needed

    Range("Table1[#All]").SpecialCells(xlCellTypeVisible).Copy sht2.Cells

    Application.DisplayAlerts = True           ' not sure if needed

    wb2.Save                                   ' already C:\Users\Ha.csv
    wb2.Close

End Sub
22.08.2017
  • Мне нравится, как ты его почистил. Однако для меня он создает таблицу из AA3, а затем не создает таблицу для 9-го столбца, а просто AA3-> Конец этого столбца. Я изменил его на Field:=1, и я думаю, что возникла проблема с копированием и вставкой. Извините, не знаю, почему это происходит :S 22.08.2017
  • действительно ли код, который вы разместили, создает таблицу с несколькими столбцами? какая линия это делает? 22.08.2017

  • 3

    Я бы даже не стал использовать VBA для получения данных, использовать Power Query и импортировать данные из исходного файла, выполнить фильтрацию в запросе и вернуть результат в таблицу в книге «FUA».

    Затем запрос можно настроить на автоматическое обновление при открытии книги «FUA» или в определении запроса.

    22.08.2017
    Новые материалы

    Угловая структура архитектуры
    Обратите внимание, что эта статья устарела, я решил создать новую с лучшей структурой и с учетом автономных компонентов: https://medium.com/@marekpanti/angular-standalone-architecture-b645edd0d54a..

    «Данные, которые большинство людей используют для обучения своих моделей искусственного интеллекта, поставляются со встроенным…
    Первоначально опубликовано HalkTalks: https://hacktown.com.br/blog/blog/os-dados-que-a-maioria-das-pessoas-usa-para-treinar-seus-modelos-de-inteligencia-artificial- ja-vem-com-um-vies-embutido/..

    Сильный ИИ против слабого ИИ: различия парадигм искусственного интеллекта
    В последние годы изучению и развитию искусственного интеллекта (ИИ) уделяется большое внимание и прогресс. Сильный ИИ и Слабый ИИ — две основные парадигмы в области искусственного интеллекта...

    Правильный способ добавить Firebase в ваш проект React с помощью React Hooks
    React + Firebase - это мощная комбинация для быстрого и безопасного создания приложений, от проверки концепции до массового производства. Раньше (знаете, несколько месяцев назад) добавление..

    Создайте API с помощью Python FastAPI
    Создание API с помощью Python становится очень простым при использовании пакета FastAPI. После установки и импорта вы можете создать приложение FastAPI и указать несколько конечных точек. Каждой..

    Веселье с прокси-сервером JavaScript
    Прокси-серверы JavaScript — это чистый сахар, если вы хотите создать некоторую общую логику в своих приложениях, чтобы облегчить себе жизнь. Вот один пример: Связь клиент-сервер Мы..

    Получить бесплатный хостинг для разработчиков | Разместите свой сайт за несколько шагов 🔥
    Статические веб-сайты — это веб-страницы с фиксированным содержанием и его постоянным содержанием. Но теперь статические сайты также обрабатывают динамические данные с помощью API и запросов...