简体   繁体   English

EXCEL VBA如果它们具有匹配的字符串,则从单独的工作簿中复制某些列

[英]EXCEL VBA Copy certain columns from seperate workbook if they have matching string

So basically I'm currently working on a project that has over 300 entries, these 300 are pulled from a master workbook that has 1000+. 所以基本上我目前在一个项目中进行工作,该项目有300多个条目,这300个条目是从具有1000多个主工作簿的书中提取的。 They each have there own unique registration so what im looking for is vba that if the registration from the workbook with 300 entries can be found in the masterwork book to copy certain from the master into the smaller one. 他们每个人都有自己独特的注册,所以我要寻找的是vba,如果您可以在母版书中找到300本条目的工作簿中的注册内容,然后将某些内容从母版复制到较小的本子中。 Had they all been in order I could of done this quite easily but due to them being in different orders I can't figure it out. 如果他们一切都井井有条,我可以很容易地做到这一点,但是由于它们的次序不同,我无法弄清楚。

Here's what I have so far, what i'm trying to do is to use arrays, so that if an array value is found in the master it would copy, however it isn't working out for me :(.. 到目前为止,这就是我想要做的,就是使用数组,这样,如果在主数据库中找到一个数组值,它将被复制,但是对我来说是行不通的:(。

Dim owb As Workbook
Dim test1(500) As String, test2(500) As String, test3(500) As String, test4  (500) As String 


With Application
.DisplayAlerts = False
.ScreenUpdating = False
.EnableEvents = False
End With

 fpath = "\Work\new location\mastercars.xlsx" 'file location
 Set owb = Application.Workbooks.Open(fpath) 'open file
For i = 1 To 500 'for each I 


    test1(i) = ThisWorkbook.Worksheets("Carlist").Cells(i, 1).Value
    test2(i) = ThisWorkbook.Worksheets("Carlist").Cells(i, 8).Value
    test3(i) = owb.Worksheets("Sheet2").Cells(i, 1).Value
    test4(i) = owb.Worksheets("Sheet2").Cells(i, 2).Value 'declare locations

    If test3(i) = test1(i) Then
        test2(i) = test4(i)
    End If
Next

Thanks 谢谢

Since they are unordered, you need two loops for testing. 由于它们是无序的,因此需要两个循环进行测试。 You don't actually need an array, you can test the values directly from the cells, and you must set them to the cells (setting values into an array changes nothing on the sheet). 您实际上不需要数组,可以直接从单元格测试值,并且必须将其设置为单元格(将值设置为数组不会改变工作表上的内容)。

Dim Master as Worksheet
Dim Slave as Worksheet

'please verify if the master and slave are correct here
Set Master = owb.Worksheets("Sheet2")
Set Slave = ThisWorkbook.Worksheets("Carlist")

For i = 1 to 500 '(the slave sheet)
   For j = 1 to 5000 '(the master sheet)
       If Master.Cells(j,1).Value = Slave.Cells(i,1).Value then
           Slave.Cells(i,8).Value = Master.Cells(j,2).Value
       EndIf
   Next
Next

Never forget to turn screen updating back to true , or you will not be able to use Excel properly after that and you will not see your inserted data properly. 永远不要忘记屏幕更新恢复为true ,否则您将无法正常使用Excel,并且您将无法正确看到插入的数据。

You don't need to disable alerts and events, they will make no difference. 您无需禁用警报和事件,它们不会造成任何影响。 Screen updating can make your code slow, so it's useful to disable it. 屏幕更新会使您的代码变慢,因此禁用它很有用。

Daniel's answer is excellent, but could be a bit slow because of all the looping (passing 5000 rows in the Slave sheet 500 times). Daniel的回答很好,但是由于所有循环(在Slave表中传递5000行500次)可能会有点慢。 It's also limited to only searching for 500 rows in the Master sheet. 它还仅限于在Master表中搜索500行。

This approach will review each row in Master , looking for the matching data in Slave . 这种方法将检查Master每一行,并在Slave查找匹配的数据。

Option Explicit  'require variables to be defined before use - always a good idea

Sub MySearch()
  On Error Goto CleanExit
  'Leave this line commented until everything is working as expected:
  'Application.ScreenUpdating = False
  'please verify if the master and slave are correct here
  Dim Master as Worksheet
  Set Master = owb.Worksheets("Sheet2")
  Dim Slave as Worksheet
  Set Slave = ThisWorkbook.Worksheets("Carlist")

  Dim LastRow as Integer
  'It appears you're looking for the value in Col H, change if necessary
  LastRow = Master.Range("H" & Master.Rows.Count).End(xlUp).Row

  Dim FoundRng as Range
  Dim Looper as Integer
  For Looper = 1 to LastRow
    'again assuming you're looking for Master column H (8)
    Set FoundRng = Slave.Find(What:=Master.Cells(Looper,8), After:=Slave.Cells(1,1), _
                   LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByColumns)
    'note: you can change LookAt to xlPart if you want a partial match
    If not FoundRng is Nothing Then 'the awkward but necessary way of saying we found something
      'I believe you want to set Master column 8 moved to Slave column 2. Adjust if necessary
      'the value we're after is in on row 1 of the FoundRng
      Master.Cells(Looper,8).Value = FoundRng.Cells(1,2).Value
    End If
  Next

:CleanExit
  'always make sure we turn screen updating back on
  Application.ScreenUpdating = True
End Sub

This approach: 这种方法:

  • Doesn't care what order the data is in in either the Master or Slave workbooks 不在乎MasterSlave工作簿中的数据顺序
  • Doesn't care how many rows of data are in either - it will process everything in Master and look everywhere in Slave 不在乎其中有多少行数据-它会处理Master中的所有内容并在Slave到处查找
  • Will update Master Column 8 with Slave Column 1 when a match is found 找到匹配项时,将用Slave列1更新Master列8
  • Using .Find() will be much quicker than looping through all 5000 rows in Slave for each row in Master 使用.Find()会比在Master每一行中循环遍历Slave所有5000行快得多
  • NOTE: use .Find() with care - it will execute with whatever settings are left from the previous use (either in code or interactively through the menu) as the base, then apply whatever settings you give it in code. 注意:谨慎使用.Find() -它会以上次使用时留下的任何设置(在代码中或通过菜单交互地)作为基础执行,然后应用您在代码中提供的任何设置。 ie if you last searched backwards from the dialog box, this code will search backwards because I didn't override that in code. 即,如果您上次从对话框中向后搜索,则此代码将向后搜索,因为我没有在代码中覆盖它。 Nothing to be worried about, just something to keep in mind. 无需担心,仅需牢记。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM