Macro to look up date in column range, insert row and paste data

1

What I want to do is to have a macro that will:

  1. Detect, on page ("Original") the value of a cell ($E8, a date)
  2. Go to another page ("Transfer"), (page name varies, but the appropriate page name comes up in "Original" $Z$1.)
  3. Look down the A column of "Transfer", which lists every Monday (dates range starts at A20, text above).
  4. Find the Monday before that $E8 date (so for $E8 = Sat 17th, it would find Mon 12th)
  5. Insert a row BENEATH that Monday row (so before the row that says Mon 19th)
  6. Erase that row (so the row goes Mon-12, blank, Mon-19
  7. Cut/Copy from ("Original $E8") the range A8:H8
  8. Go to the "Transfer" page
  9. Insert that A8:H8 selection into the row created at 5.
  10. Loop back and do the same thing for $E9 until all the info has been put into "Transfer".

The cells I've given are the right cells, the dates I've just made up (they vary for each account anyway).

Eric has very kindly provided me with a code that I have modified, which is as follows:

 Public Sub do_stuff()
 Dim date_to_look_for As String
 Dim row As Integer

 date_to_look_for = Range("'Original'!K8").Value
                    '^L: This is the cell that you are reading from. Ensure it is the MONDAY formula
 row = 20
 '^L: This is where the Transfer date values start

 Do Until row = Range("'Transfer'!A1").End(xlDown).row + 1  'create our loop.
 'Notice that the .end function will find the end of the data in a column

If Range("'Transfer'!A" & row).Value = date_to_look_for Then
        '^L: Look for Original (X) Value specified above (make sure it's Monday).

    Range("'Transfer'!" & row + 1 & ":" & row + 1).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
          '^L: Once

    Range("'Transfer'!A" & row + 1 & ":H" & row + 1).Value = Range("'Original'!A8:H8").Value

         '^L:This is WHERE it will paste                           '^L: This is what will copy
    Exit Sub 'no sense in running loop more if already found
End If
 row = row + 1
 Loop

 'If code gets here then the date was never found! so tack to end of list
 Dim endrow As Integer
 endrow = Range("'Transfer'!A1").End(xlDown).row

 Range("'Transfer'!A" & endrow & ":H" & endrow).Value = 
 Range("'Original'!A8:H8").Value
 '^L: What is this?

 End Sub

(The L: messages are my notes as I worked out what each section did - please feel free to correct me if I've misunderstood. The other green 'notes are Eric's and I'm not sure I understand those bits. I don't really need to though, as long as it works, but if you feel like educating me on coding please feel free :D)

My problem is now how to make it loop so it works its way down the original values (in this case the K column, so it goes to K9, K10, etc, and does the same thing? Also, can it CUT instead of COPY, and remove from Original sheet once transferred?

Thanks to everyone who assisted, you guys are great!

Lauren

Posted 2017-06-16T18:09:29.013

Reputation: 11

I don't understand why I can't get help in the first place, to be quite frank. Might as well try and cast a wider net to get some assistance. I can't code and I've spent days on this - I just cannot make it work. – Lauren – 2017-06-16T18:15:57.120

And I posted two existing codes. You said neither would work without elaborating why. Even though one occasionally does - I had hoped I could modify that. And when I showed the error that was causing the crash, you didn't assist. If you can't or wont help that's fine. But maybe someone else will. – Lauren – 2017-06-16T18:26:20.897

You responded here but not there. I could only assume you either didn't want to or couldn't help. When I try to run my co-workers macro, it crashes when it gets to: " If Not found Is Nothing Then". Excel freezes and if I don't ESC out of it, it crashes." @ScottCraner – Lauren – 2017-06-16T18:32:29.747

Lauren could you put up a screenshot of both the "Original" and "Transfer" worksheets? You can void the data, I would just like to see the sheet structure. I can help you out. – Nate – 2017-06-16T18:38:29.790

I just went through your old code and what you have posted here. Just some general notes that may help you figure out your problem. First of all Range("'Sheet1'!A2").value is a good way to reference cell values instead of having to select and then do all of the other business the macro recorder does. When you "goto" or "transfer", most can be done in a similar format as Range("'Sheet2'!A2").value = Range("'Sheet1'!A2").value. Since most of your post is about copying and pasting, using this method should clear up most of what you are doing.. just replace the sheet names, columns, and rows – Eric F – 2017-06-16T18:43:48.350

Thanks Eric, that's good to know! I'll have a play around and see if that works. Currently the code isn't working at all though so wish me luck :) – Lauren – 2017-06-16T18:48:06.383

@ScottCraner You're right. I'm sorry. – music2myear – 2017-06-16T18:55:34.363

What are you talking about? I posted two days ago and the response I got didn't work, so I tried to be clearer in my answer and reposted. I posted here as well hoping more people might assist. I gave the codes and the pictures when requested. You said they weren't going to work but didn't elaborate. – Lauren – 2017-06-16T19:03:16.493

Answers

1

This should do what you are looking for. I commented the code so you can read exactly what's happening. Note that this code using Range type variable, which means that the variables rTransfer and rOriginal are referencing actual cells in the worksheet.

Hope this helps! Good luck!

Sub TransferMyData()
'Declare the variables to be used in the code
Dim wsTransfer As Worksheet, wsOriginal As Worksheet
Dim rTransfer As Range, rOriginal As Range, rCopyRange As Range
Dim dMonday As Variant
Dim iRow As Integer

'Set the worksheet variable, this makes is easier than constantly referencing each sheet in the code all the time
Set wsTransfer = ThisWorkbook.Worksheets("Transfer")
Set wsOriginal = ThisWorkbook.Worksheets("Original")

'Set rOriginal to reference range E8, the first cell we are checking for a date to transfer
Set rOriginal = wsOriginal.Range("E8")

'Run this loop over and over until the cell referenced in rOriginal is blank.
'At the bottom of the loop we shift rOriginal down by one
Do While rOriginal <> ""
    'Find the Monday of the week for rOriginal
    dMonday = rOriginal - Weekday(rOriginal, 3)

    'Format dMonay to match the Transfer worksheet - Commented out
    'dMonday = Format(dMonday, "dd-mm-yy")

    'Set the cell of rTransfer using the Find function (Search range A:A in wsTransfer for the monday we figured out above)
    Set rTransfer = wsTransfer.Range("A:A").Find(dMonday)

    'Error check. If rTransfer returns nothing then no match was found
    If rTransfer Is Nothing Then
        MsgBox ("Can't find the Monday for ") & rOriginal & ". Searching for Value " & dMonday
        Exit Sub
    End If

    'Check if there was already some data transfered in for that week (rTransfer.Offset(1,4) references the 'E' column of the row below).
    'If there is a value there, shift down by one and check again
    Do Until rTransfer.Offset(1, 4) = ""
        Set rTransfer = rTransfer.Offset(1, 0)
    Loop

    'Insert a blank row below rTransfer using the offset function
    rTransfer.Offset(1, 0).EntireRow.Insert

    'Set iRow to be the row number of rOriginal to be used below
    iRow = rOriginal.Row

    'Set the range rCopyRange to be the range A:H of the row for iRow (See https://www.mrexcel.com/forum/excel-questions/48711-range-r1c1-format-visual-basic-applications.html for explanation)
    Set rCopyRange = wsOriginal.Range(Cells(iRow, 1).Address, Cells(iRow, 8).Address)

    'Copy the range rCopyRange into the blank row we added
    rCopyRange.Copy rTransfer.Offset(1, 0)

    'Offset our rOriginal cell down by one and restart the loop
    Set rOriginal = rOriginal.Offset(1, 0)

    'Clear out the copied range. Can replace with rCopyRange.Delete if you want to delete the cells and have everything shift up
    rCopyRange.Clear

    'Simple error check, if for some reasone you're stuck in an endless loop this will break out
    If rOriginal.Row > 999 Then
        MsgBox "Error! Stuck in Loop!"
        Exit Sub
    End If
Loop

End Sub

Nate

Posted 2017-06-16T18:09:29.013

Reputation: 579

It looks really good thank you Nate, but it's not coming up with a value. I get the error "can't find the Monday for 22/11/16". The Original-E8 value, the 22/11/16 was a Tuesday so it should have slotted itself in between the Transfer-A row saying the 21st and the 28th. Any thoughts? – Lauren – 2017-06-16T19:44:02.993

It's the formating for the value dMonday. Google the Format() function and add a line dMonday = Format(dMonday, "Your Format Here") before the find. Try that and let me know, I'll be busy for the next while. – Nate – 2017-06-16T19:58:48.250

I modified the code above to have the error show you exactly what it's searching for. This will help you figure out why it can't find a match. MsgBox ("Can't find the Monday for ") & rOriginal & ". Searching for Value " & dMonday – Nate – 2017-06-16T20:35:58.627

There, I also added the line to fix the formatting. I'm pretty sure this will do the trick. – Nate – 2017-06-16T20:48:18.977

Thanks Nate, Eric's seems to be working kind of OK, I've still got a few things to correct though. I'll amend the OP, if you don't mind taking a look? Thanks so much BTW! – Lauren – 2017-06-16T20:48:40.600

But please dont delete yours or anything :D – Lauren – 2017-06-16T20:49:00.917

Sure thing, no slight taken whatsoever! You should try once, just to see ;) – Nate – 2017-06-16T20:53:06.757

I definitely will, its just it's 5am and I've been up for over 36 hours. I'm not even sure this isn't a hallucination and I'll wake up with the macro still crashing and start crying :D. – Lauren – 2017-06-16T20:56:13.190

https://xkcd.com/1319/ I'm pretty sure this graph sums up what you're doing right now. Cheers! – Nate – 2017-06-16T20:59:45.863

XD That's entirely accurate! I tried your code and did some fiddling with the spreadsheet and I got it working to the same stage Eric's is currently at. But with yours, I have to manually type the dates in Transfer, and delete your "dMonday = Format(dMonday, "dd-mm-yy")" to make it work. It works if I click-drag the date cells in A down but not if there is any formula - has to be text. Which is fine, I can live with that, but any workaround off the top of your head? Also, how do I set it to delete the data once it's transferred? – Lauren – 2017-06-17T02:57:37.403

Hopefully it looping all the way down through your list and copying the values in? I edited the code to add a line rCopyRange.Clear at the bottom. This will clear out the cells in the Original sheet after they are copied, row by row. You can also change it to rCopyRange.Delete and it will delete the entire cells, shifting everything up. Choose which works best for you. And I fixed a bug I found, where it inserts the new row. I changed it to rTransfer.Offset(1, 0).EntireRow.Insert, adding the EntireRow bit, or it was just inserting cells, not a whole new row. – Nate – 2017-06-17T16:37:02.450

As far as the date thing goes, I'm 95% sure it's a formatting thing. I would have to look at the actual workbook to figure it out. – Nate – 2017-06-17T16:37:47.243

Hi Nate, thanks for that. I modified it myself to work but I will keep an eye on those changes when I get ready to use the proper sheet (using a dummy at the moment). I posted on MrExcel with my issues if you'd prefer to go there where discussions are better ("Macro conflict when inserting columns and dates match.") I'm still having an issue picking up A:A dates that aren't typed or dragged down (the real sheet uses a formula, and wont work even when I format dd-mm-yy). Also if the date in E is a Monday, it pasted ABOVE the corresponding Monday A:A, not below it, so it's under the wrong week. – Lauren – 2017-06-18T02:40:25.847

I did make a work-around for the "wrong line" thing, where I make the Original Col A "=[E:E+.01]", then filter column A:A so that the original date shows up the same but reads it as 0.1 bigger. It works but it's not ideal so any ideas you have that would be better would be great :D. – Lauren – 2017-06-18T02:49:43.373

0

So here is an example that I believe captures what you are trying to do in a general sense. I set up two tabs on my workbook labeled Transfer and Original as you have. I set up my Original Tab to look like the following:

enter image description here

The data in A, B, C, D doesn't really matter. I have Column F and G to determine which date is the "last Monday". This of course can be done in one cell but I broke it apart so you can understand better. So in this example, my F2 cell has =WEEKDAY(A2)-2 as the WEEKDAY function returns the day of the week as a number. I have G2 set as =A2-F2 to actually show the "last Monday date".

I have my Transfer sheet looking like this:

enter image description here

So from here we have to have the macro look up which row is the last monday date from the Transfer tab. We also must make sure it exists. In my example if it doesn't exist I will just tack it to the bottom...

Here is what I wrote for my example with a lot of comments:

Public Sub do_stuff()
Dim date_to_look_for As String
Dim row As Integer

date_to_look_for = Range("'Original'!G2").Value
row = 2 'whichever row is your start row for the data on the Transfer tab

Do Until row = Range("'Transfer'!A1").End(xlDown).row + 1  'create our loop.
'Notice that the .end function will find the end of the data in a column

    If Range("'Transfer'!A" & row).Value = date_to_look_for Then
        'row found for Monday! Do our magic here!

        'insert a blank spot at the row found + 1
        Range("'Transfer'!" & row + 1 & ":" & row + 1).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
        'now copy data here
        Range("'Transfer'!A" & row + 1 & ":E" & row + 1).Value = Range("'Original'!A2:E2").Value
        Exit Sub 'no sense in running loop more if already found
    End If
row = row + 1
Loop

'If code gets here then the date was never found! so tack to end of list
Dim endrow As Integer
endrow = Range("'Transfer'!A1").End(xlDown).row

Range("'Transfer'!A" & endrow & ":E" & endrow).Value = 
Range("'Original'!A2:E2").Value

End Sub

Notice how I can copy data at one time using the Range().value function and also notice how I can specify a range too.

After running the macro shown above you should see this in the Transfer tab:

enter image description here

Eric F

Posted 2017-06-16T18:09:29.013

Reputation: 3 070

Comments are not for extended discussion; this conversation has been moved to chat.

– DavidPostill – 2017-06-16T20:55:23.920