For 4 million records between two sheets, use a database. Excel is not a database.
If you insist on treating Excel as a database, I would suggest using ADODB. See this answer for a similar problem and solution.
Name each of the columns in Sheet1 that you want to write to by placing the name on the first row of each column. As an example, let me call them F1 , F2 , F3 , F4 and F5 . Also specify a column with common data between Sheet1 and Sheet2; for example, we will call it F0 .
Then, if your version of Office allows this, you can publish this expression:
UPDATE [Sheet1$] INNER JOIN [Sheet2$] ON [Sheet1$].F0 = [Sheet2$].F0 SET [Sheet1$].F1 = [Sheet2$].F1, [Sheet1$].F2 = [Sheet2$].F2, [Sheet1$].F3 = [Sheet2$].F3, [Sheet1$].F4 = [Sheet2$].F4, [Sheet1$].F5 = [Sheet2$].F5
If not, you can use the CopyFromRecordset method with the recordset generated from the following SQL statement:
SELECT s1.F0, Iif(s2.F0 Is Not Null, s2.F1, s1.F1), Iif(s2.F0 Is Not Null, s2.F2, s1.F2), Iif(s2.F0 Is Not Null, s2.F3, s1.F3), Iif(s2.F0 Is Not Null, s2.F4, s1.F4), Iif(s2.F0 Is Not Null, s2.F5, s1.F5) FROM [Sheet1$] AS s1 LEFT JOIN [Sheet2$] AS s2 ON s1.F0 = s2.F0