Макрос цикла для копирования диапазона пользовательского ввода и вставки в диапазон пользовательского ввода в неизвестной открытой книге

Я очень новичок в VBA. Я уже несколько недель пытаюсь разработать код, который будет имитировать функции vlookup и hlookup в Excel.

Я создаю макрос, который копирует и вставляет данные из одной книги в другую.

Данные будут иметь эталонные значения в левом столбце как исходной книги, так и книги назначения.

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

Копируемые данные будут располагаться на расстоянии 4 столбцов от эталонных значений. Данные (вместе с эталонными значениями) могут состоять из тысяч строк и сотен столбцов.

Целевая рабочая книга и рабочая книга, в которой находятся исходные данные, будут открыты.

Пользователь укажет расположение эталонных значений как в исходной, так и в целевой книге.

Пользователь также укажет диапазон копируемых данных.

Все данные будут скопированы.

Вот пример файла, над которым я работал. Мои фактические данные будут намного больше, чем это. Данные скопированы отсюда: Исходная рабочая тетрадь

Затем данные вставляются в эту книгу. Целевая рабочая книга будет выглядеть аналогично, но вы можете видеть, что справочные данные расположены в другом порядке: Целевая рабочая книга< /а>

Кроме того, после успешного цикла на том же листе (где диапазон вставки — тот же лист в той же книге) я получаю эту ошибку: я также получаю «Ошибка выполнения 91. Переменная объекта или переменная блока не установлена». Это то, что я получил до сих пор:

> Sub copyv5input()
>  
> Dim wsSrc As Worksheet Dim wbSrc As Workbook Dim wsTgt As Worksheet
> Dim wbTgt As Workbook Dim vRng1 As Range Dim vNo As Range Dim rNum As
> Integer Dim vRef1 As Range Dim vRng2 As Range Dim vDest1 As Variant
> Dim vDest2 As Variant Dim vDest3 As Range Dim cNum As Integer Dim
> cNum2 As String Dim vNew2 As Range
> 
> rNum = 1 
> cNum = 1 
>     Set vRng1 = Application.InputBox("Select the range of reference data:", Type:=8)    '1
>     Set vRef1 = vRng1.Cells(rNum, cNum)     '1
>     
>     
>     
>     Set vRng2 = Application.InputBox("Select the reference data range for destination:", Type:=8)   '2
>      
>         
>    
>     Set vDest1 = vRng2.Find(what:=vRef1)    '2
>     Set vDest2 = Range(vDest1.Address)      '2
>     Set vDest3 = vDest2.Offset(0, 1).Resize(, 4)    '2
> 
> Do While vRef1 <> ""
> 
> Set vNo = vRef1.Offset(0, 4).Resize(, 4)    '1
>          
>          If vRef1 = vDest1 Then
>         
>             vNo.copy Destination:=vDest3
>         
>         
>          End If
>     
>     rNum = rNum + 1
>         
>             Set vRef1 = vRng1.Cells(rNum, cNum)
>             Set vDest1 = vRng2.Find(what:=vRef1)
>             Set vDest2 = Range(vDest1.Address)      '2
>             Set vDest3 = vDest2.Offset(0, 1).Resize(, 4)
>      Loop
>        
> 
> End Sub

Заранее спасибо!


person Jiggler    schedule 28.01.2018    source источник


Ответы (2)


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

  1. выберите список значений, которые вы хотите найти
  2. выберите диапазон с этими значениями и дополнительными данными в столбцах, которые вы хотите вернуть
  3. добавить искомый столбец данных в список ссылок

Вы можете использовать свойство Application.WorksheetFunction для vlookup или, как я бы это сделал, перебрать каждое значение в поисках совпадения, а затем вернуть значение в той же строке, но в другом столбце. Это может быть немного медленным для длинных списков данных, но это просто и будет работать.

 Sub copyv5input2()


 Dim vRng1 As Range

 Dim rNum As Integer
 Dim rNum2 As Integer
 Dim vRef1 As Range
 Dim vRng2 As Range
 Dim cNum As Integer
 Dim lookupV As String
 Dim foundR As Long
With Application
    .ScreenUpdating = False
    .Calculation = xlCalculationManual
End With

Set vRng1 = Application.InputBox("Select the range of reference data:", Type:=8)
Set vRng2 = Application.InputBox("Select the reference data range for destination:", Type:=8)   '2
cNum = Application.InputBox("Select the column number you want to return from reference data:")


For rNum = 1 To vRng1.Rows.Count

    lookupV = vRng1.Cells(rNum, 1).Value
    For rNum2 = 1 To vRng2.Rows.Count
        If vRng2.Cells(rNum2, 1) = lookupV Then
            vRng1.Cells(rNum, 1).Offset(0, 1) = vRng2.Cells(rNum2, cNum).Value
            foundR = foundR + 1
            GoTo 10
        End If
    Next rNum2
10
Next rNum

With Application
    .ScreenUpdating = true
    .Calculation = xlCalculationAutomatic

End With
MsgBox "complete, " & foundR & " values returned", vbInformation, "auto lookup"

 End Sub
person David wyatt    schedule 28.01.2018
comment
Спасибо, Дэвид. Прошу прощения, что не передал это должным образом. Причина смещений в моем коде заключается в том, что данные начинаются на 4 столбца от опорных ячеек. Кроме того, идея состоит в том, чтобы вставить каждый столбец данных, а не просто выбрать один столбец данных. Целевая рабочая книга будет иметь те же ссылки, но порядок строк будет другим. - person Jiggler; 28.01.2018
comment
Привет, Джигглер, не проблема, наверное, это был я больше, чем ты. Итак, чтобы уточнить, хотите ли вы вернуть более одного столбца (например, 4, затем 5, затем 6 и т. д.) или вы выбираете только ссылочный столбец. Если это так, когда вы запускаете мой код, выберите всю таблицу в справочных данных (столбцы с 1 по 5), затем введите столбец 5 в следующем поле ввода. - person David wyatt; 28.01.2018
comment
Привет @David Wyatt. Мне удалось (в конце концов) понять ваш код. Я изменил его, удалив объявление cNum, а затем в вашем цикле добавив переменную объекта range.copy, а затем вуаля! Спасибо еще раз - person Jiggler; 30.01.2018
comment
Приятно слышать, помогать - person David wyatt; 30.01.2018

Добро пожаловать в Stack Overflow!

Вы можете использовать функции рабочего листа Excel с помощью функции VBA: Application.Worksheet.

Например, у меня есть функция листа:

=VLOOKUP(D7,$A$2:$B$5,2,FALSE)

... поэтому в VBA я мог бы открыть диалоговое окно MsgBox с тем же результатом, используя:

MsgBox Application.WorksheetFunction.VLookup(Range("D7"), Range("$A$2:$B$5"), 2, False)

Дополнительная информация:

person ashleedawg    schedule 28.01.2018
comment
Спасибо за это. Однако я не уверен, что это сработает, так как это не позволяет легко достичь цели. Как я уже сказал, я работаю с огромными объемами данных. Если у меня есть данные из 2000 строк и 400 столбцов, которые необходимо реплицировать в другой книге в другом порядке строк, то, если я использую функцию vlookup в vba, мне нужно будет запустить этот макрос несколько раз для достижения результата. То, что вы предложили, вернет ссылку на один столбец. В вашем примере столбец 2. Мне нужно, чтобы это повторялось 400 раз, чтобы получить 400 столбцов данных. Разве макрос копирования и вставки не более эффективен? Спасибо еще раз - person Jiggler; 28.01.2018
comment
Было бы полезно, если бы вы отредактировали свой вопрос, чтобы поделиться примером того, что у вас есть, и что нужно посмотреть например, когда он закончен. Есть несколько советов в минимально воспроизводимом примере, а также ознакомьтесь с Написание идеального вопроса (это парень, который только что набрал миллион повторений, ответив на 34 000 вопросов, так что он знает о чем говорит... :-) - person ashleedawg; 28.01.2018