Nano Hash - криптовалюты, майнинг, программирование

Использование функции сопоставления и индекса VBA

Попытка использовать match & Index с указанными диапазонами. Не распознает RefreshDrNumbers в коде.

Я использую функцию Case для указания диапазонов.

Не удается заставить функции Case, Match & Index соединиться или поговорить друг с другом?

Другой форум, о котором я спрашивал,

https://www.mrexcel.com/board/threads/add-ranges-to-match-and-index-functions.1162701/

Private Sub Jobcard_Demands_Click()

     If Jobcard_Demands = ("Drawing No`s Update") Then

    Dim matchRange As Range
    Dim ODict As Object
    Dim PartsListLastRow As Long, DestLastRow As Long
    Dim LookupRange As Range
    Dim i As Integer
    Dim wsSource As Worksheet, wsDest As Worksheet
    
    Set wsSource = ThisWorkbook.Worksheets("Parts List")
    Set wsDest = ThisWorkbook.Worksheets("Job Card Master")
    
    PartsListLastRow = wsSource.Range("A" & Rows.Count).End(xlUp).Row
    DestLastRow = wsDest.Range("A" & Rows.Count).End(xlUp).Row
    
    'This holds the lookup range (including both the lookup key
    'column and the value column)
    Set matchRange = wsSource.Range("E1:F" & PartsListLastRow)
    
    'Get a dictionary of all the lookup values. The function, as
    'defined below, takes the range as well as the relative column
    'of the keys and values. In our case, the first column of our
    'range has the keys, and the second has the values
    Set ODict = GetDictionary(matchRange, 5, 6)
    
    'Below, define the lookup range. In your specific code, this
    'varies based on the combobox value, but I think you'll be able
    'to figure out how to define it (I'm just hardcoding mine
    Set LookupRange = wsDest.Range("A1:A" & DestLastRow)
    
    'Loop over the lookup range
    For i = 1 To DestLastRow
        'Since the GetPartInfo function handles cases where there isn't a match
        ' (it returns a blank string), you don't have to use an if/else statement
        wsDest.Range("B" & i).Value = GetPartInfo(ODict, wsDest.Range("E" & i).Value)
    Next i
    End If
End Sub

Private Function GetDictionary(rng As Range, keyCol As Long, valCol As Long) As Object
    Dim sht As Worksheet
    Dim rCell As Range
    Dim ODict As Object
    
    Set sht = rng.Parent
    Set ODict = CreateObject("Scripting.Dictionary")
    
    For Each rCell In rng.Columns(keyCol).Cells
        If Not ODict.Exists(rCell.Offset(, keyCol - 1).Value) Then
            ODict.Add rCell.Offset(, keyCol - 1).Value, rCell.Offset(, valCol - 1).Value
        End If
    Next rCell
    
    Set GetDictionary = ODict
End Function

'This is just a helper function to de-clutter the main subroutine. Returns an
' empty string in cases where the part doesn't exist in the dictionary
Private Function GetPartInfo(ByRef ODict As Object, sKey As String)
    Dim Output As String
    
    Output = ""
    
    If ODict.Exists(sKey) Then
        Output = ODict(sKey)
    End If
    
    GetPartInfo = Output
End Function
23.02.2021

  • что такое RefreshDrNumbers? это функция? Если да, то можно и его вставить? 23.02.2021
  • Идея заключалась в том, чтобы использовать его в коде под подзаголовком, чтобы связать 2 вместе. Я делал это раньше, и это сработало? 23.02.2021
  • RefreshDrNumbers не является родным vba, поэтому это должна быть функция где-то в рабочей книге. Возможно, там, где вы его использовали, он существовал, а здесь его нет. 23.02.2021
  • Когда вы говорите о родном VBA, что бы вы порекомендовали, чтобы он работал? 23.02.2021
  • Вам нужно будет найти функцию или надстройку, которая использовалась в другой книге, и добавить ее в эту книгу. Вне этого мы не можем помочь. 23.02.2021
  • Вам нужно добавить аргументы к RefreshDrNumbers() для передачи в указанных диапазонах, поэтому myFunction(r as excel.range) и вызывать как myFunction worksheets(1).range("a1:c100") 23.02.2021
  • Вы столкнетесь с проблемами масштаба. Ряд переменных, которые вы вызываете в функции RefreshDrNumbers(), относятся к подпрограмме Refresh_Drawing_Numbers_Click. 23.02.2021
  • Можно ли как-то убрать нижний сабвуфер? 23.02.2021
  • excelanytime.com/excel/ и excel-easy.com/vba/examples/variable-scope.html 23.02.2021

Ответы:


1

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

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

Sub RefreshStuff()
    Dim matchRange As Range
    Dim oDict As Object
    Dim lastRow As Long
    Dim lookupRange As Range
    Dim wsDest As Worksheet
    
    'This holds the lookup range (including both the lookup key
    'column and the value column)
    Set matchRange = Sheets("Parts List").Range("E1:F6")
    
    'Get a dictionary of all the lookup values. The function, as
    'defined below, takes the range as well as the relative column
    'of the keys and values. In our case, the first column of our
    'range has the keys, and the second has the values
    Set oDict = GetDictionary(matchRange, 1, 2)
    
    'Below, define the lookup range. In your specific code, this
    'varies based on the combobox value, but I think you'll be able
    'to figure out how to define it (I'm just hardcoding mine
    lastRow = 10
    Set wsDest = Sheets("Job Card Master")
    Set lookupRange = wsDest.Range("A1:A" & lastRow)
    
    'Loop over the lookup range
    For i = 1 To lastRow
        'Since the GetPartInfo function handles cases where there isn't a match
        ' (it returns a blank string), you don't have to use an if/else statement
        wsDest.Range("B" & i).Value = GetPartInfo(oDict, wsDest.Range("A" & i).Value)
    Next i
End Sub


Private Function GetDictionary(rng As Range, keyCol As Long, valCol As Long) As Object
    Dim sht As Worksheet
    Dim rCell As Range
    Dim oDict As Object
    
    Set sht = rng.Parent
    Set oDict = CreateObject("Scripting.Dictionary")
    
    For Each rCell In rng.Columns(keyCol).Cells
        If Not oDict.exists(rCell.Offset(, keyCol - 1).Value) Then
            oDict.Add rCell.Offset(, keyCol - 1).Value, rCell.Offset(, valCol - 1).Value
        End If
    Next rCell
    
    Set GetDictionary = oDict
End Function

'This is just a helper function to de-clutter the main subroutine. Returns an
' empty string in cases where the part doesn't exist in the dictionary
Private Function GetPartInfo(ByRef oDict As Object, sKey As String)
    Dim output As String
    
    output = ""
    
    If oDict.exists(sKey) Then
        output = oDict(sKey)
    End If
    
    GetPartInfo = output
End Function
23.02.2021
  • Я попробовал ваш код, но он не работает. Доходит до установки диапазона соответствия, а затем останавливается? 24.02.2021
  • dropbox.com/t/ho8TbmlNKoxOiRZZ 24.02.2021
  • Я отправил вам свою рабочую тетрадь, чтобы вы могли видеть, что происходит. Ссылка выше. Я уверен, что ваш код будет работать, но есть ли какая-то моя ошибка? 24.02.2021
  • @user14435479 user14435479 Я не хочу оставлять вас в беде, но на самом деле я не могу загружать внешние файлы на свой рабочий компьютер. Можете ли вы дать какие-либо отзывы о том, что происходит, когда он достигает строки Set matchRange? Выдает ошибку? Можете ли вы пройтись по коду, чтобы увидеть, есть ли конкретная девиантная запись, которая вызывает проблему? 24.02.2021
  • Установленный диапазон соответствия = Ничего 24.02.2021
  • @user14435479 user14435479 Это странно, поскольку мы просто присваиваем диапазон переменной. Правильно ли указано название листа (без опечаток)? Вы жестко кодируете свой диапазон (например, E1: F6) или используете динамический подход? 24.02.2021
  • Динамический диапазон см. ниже. Названия листов правильные 24.02.2021
  • Установите matchRange = wsSource.Range(E1:F и PartsListLastRow) 24.02.2021
  • Можете ли вы проверить значение PartsListLastRow в случае сбоя кода? 24.02.2021
  • Он показывает 1242 строку, которая правильная 24.02.2021
  • @user14435479 user14435479 Не могли бы вы отредактировать свой исходный пост и просто скопировать и вставить свой код, как он у вас есть? 24.02.2021
  • Я добавил новый код в исходное сообщение 24.02.2021
  • @user14435479 user14435479 Кажется, я нашел проблему. В строке кода `Set ODict = GetDictionary(matchRange, 5, 6), you should actually be using Set ODict = GetDictionary(matchRange, 1, 2)`. То, как я настроил функцию для загрузки словаря, принимает относительные столбцы в пределах диапазона. Поскольку наш диапазон — E1:F1252, мы хотим, чтобы ключевой столбец был первым в этом диапазоне, а значения — вторым столбцом этого диапазона. Я думаю, вы ввели их как 5-й и 6-й столбцы рабочего листа. Попробуйте это и посмотрите, получится ли. 24.02.2021
  • Извините, все еще не работаете? 25.02.2021
  • @user14435479 user14435479 Я загрузил книгу на свой компьютер, и кажется, что код работает. Итак, мы должны убедиться, что у нас есть совпадающая логика. В настоящее время код перебирает столбец E в Job Card Master и ищет соответствующие значения в столбце E в Parts List. Это на самом деле то, что вы хотите? Я попытался вручную найти названия отдельных частей с одного листа на другой, и случайная выборка, которую я искал, на самом деле не была найдена. У нас есть несоответствующие столбцы? У нас недопонимание? 25.02.2021
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

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

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..