An alternative which may, or may not, be quicker would be to keep the old and new data on separate worksheets and use ADODB and SQL to build an OUTER JOIN
which would create a recordset of those values in the new data that are not in the old data. These links are from @RubberDuck's answer to another review another review. Here is the MSDN page on querying the Excel data source with ADODB. Once you have a recordset, you can use the CopyFromRecordset method of Range to paste into the current workbook.
An alternative which may, or may not, be quicker would be to keep the old and new data on separate worksheets and use ADODB and SQL to build an OUTER JOIN
which would create a recordset of those values in the new data that are not in the old data. These links are from @RubberDuck's answer to another review. Here is the MSDN page on querying the Excel data source with ADODB. Once you have a recordset, you can use the CopyFromRecordset method of Range to paste into the current workbook.
An alternative which may, or may not, be quicker would be to keep the old and new data on separate worksheets and use ADODB and SQL to build an OUTER JOIN
which would create a recordset of those values in the new data that are not in the old data. These links are from @RubberDuck's answer to another review. Here is the MSDN page on querying the Excel data source with ADODB. Once you have a recordset, you can use the CopyFromRecordset method of Range to paste into the current workbook.
It is good to see that you are using Option Explicit
and that you are controlling ScreenUpdating
and Calculation
.
In addition to the answer given by @RubberDuck, I'd like to point out a couple of things.
You only expect 4,000 or so lines of data but are currently filling 10,000 rows with formulas (presumably as a safeguard) and clearing and copying that chunk of data. You are more than doubling (4,000 vs 10,000) the calculation effort required in Excel. Working out the exact number of lines of data and using that size range will let you remove the overhead.
Also, look at your formulas.
Range("T10").Formula = "=IF(IF(ISERROR(VLOOKUP('New Data'!E10,'New Data'! $O10ドル:$S10000,1,ドルFALSE))=TRUE,'New Data'!E10,"""")=0,"""",IF(ISERROR (VLOOKUP('New Data'!E10,'New Data'!$O10ドル:$S10000,1,ドルFALSE))=TRUE,'New Data'! E10,""""))"
Range("U10").Formula = "=IF(IF(ISERROR(VLOOKUP('New Data'!B10,'New Data'! $L10ドル:$S10000,1,ドルFALSE))=TRUE,'New Data'!B10,"""")=0,"""",IF(ISERROR (VLOOKUP('New Data'!B10,'New Data'!$L10ドル:$S10000,1,ドルFALSE))=TRUE,'New Data'! B10,""""))"
You have got what looks like the same VLOOKUP
function call twice on each line wrapped up in an ISERROR
and nested IF
functions. Consider replacing the IF(ISERROR(VLOOKUP
with the simpler IFERROR(VLOOKUP
if your version of Excel supports it. The VLOOKUP
only looks at the first column, so why not replace with the MATCH
function. If you forget about the ISERROR
completely, you could just use the MATCH
function and then change the AutoFilter
criteria to be Criteria1:="#N/A"
. Your formulas could (if I've understood) become:
Range("T10").Formula = "=MATCH('New Data'!E10,'New Data'!$O10ドル:$O$" & lastRowNum & ",0)
Range("U10").Formula = "=MATCH('New Data'!B10,'New Data'!$L10ドル:$L$" & lastRowNum & ",0)
Where lastRowNum
is the variable that stores the last row that contains values. You would then apply the autofilter using the new criteria and then copy columns B and E.
You might want to look at directly assigning the values from one range to another (dataSheet.Range("X10:X" & lastRowNum).Value = dataSheet.Range("V10:V" & lastRowNum).Value
) which will be quicker than Copy ... PasteSpecial Paste:=xlPasteValues
.
An alternative which may, or may not, be quicker would be to keep the old and new data on separate worksheets and use ADODB and SQL to build an OUTER JOIN
which would create a recordset of those values in the new data that are not in the old data. These links are from @RubberDuck's answer to another review. Here is the MSDN page on querying the Excel data source with ADODB. Once you have a recordset, you can use the CopyFromRecordset method of Range to paste into the current workbook.