Using a Loop to Copy and Paste - vba

I am a beginner VBA coder and have been trying to figure out how to work a loop within my spreadsheet. I am attempting to declutter a collection of loan information I have, but just as a basic framework for the specifics of my question, I have generated the following random numbers in Column ("A:A") in the first Worksheet of the Workbook:
5
241
4
5
648
87
65
74
52
1
The loop I'm using is:
Sub LoopTest()
Dim i As Integer
For i = 1 To 10
Range(i,1).Select.Copy Destination:=Range(i,5)
Next i
So essentially I am trying to copy the first cell in Row 1, Column 1 and paste it to Row 1, Column 5 and then loop to Row 2, Column 1 and paste it to Row 2, Column 5, etc. etc. until I loop through Row 10. Preferably, I would like to loop from the first row data to whatever is the last row of data (and I'm aware that is possible) but I am unaware how to do so.
Thanks.

I am unsure why you would need to do this by row. Couldn't you copy A1:A:10 and paste it to E1:E10 instead? This would keep you from having to loop. If you were to copy then you could do it with a Range.Copy call:
Range("A1").Copy Range("E1")
This copies A1 to E1.

Related

How to Find the Length of a Column in VBA with a Variable Last Row

I'm a beginner to vba and hope to use it in order to automate a process. I have a computer program that provides me an excel spreadsheet, where the amount of data in the columns can change. For example, I could have a column of length 9 one time:
1
3
2
4
24
23
432
55
2
Or a column of length 5 (note: actual column sizes are usually in the thousands):
1
2
3
4
8
I want to write code that will grab this column, not knowing how long the column will be. Something like:
Dim list1 As Array
'I don't know how to find the upper bound
list1 = Range("A1:A" & Upper Bound).Value
Any help is appreciated. Thanks!
If you are working with constant values in these columns and are working with larger amounts of cells in these columns, it could be useful to use the count function:
dim x As Long
x = Worksheets(*sheet name*).Range(*column range*).Cells.SpecialCells(xlCellTypeConstants).Count
x is being passed the number of non-empty cells in your column. So you may want to be careful in your column range not to include any headers, if applicable.
I believe this will get you the last row. You might need to be careful if you're looking to count all values (e.g. the first couple rows are blank).
Dim lastRow As Long
lastRow = Cells(Rows.Count, "A").End(xlUp).Row
To get the data from column A into a 2d variant array, use the following:
Dim vA As Variant
vA = [a1:index(a:a,counta(a:a))]
This assumes that there are no blank cells within the data, and that the data starts in row 1.

How to compare a list of rows to another list of rows in Excel?

I am trying to figure out if there are any differences between a list of data with another. In order for a row of data to "match" with another row, the row must have the same values in their corresponding column. The rows themselves do not have to be in any particular order. In particular, I am dealing with a parts list, where there are part numbers, descriptions, etc. I am trying to figure out if any rows of data are different from rows of data from another list.
I found Compare two sheets using arrays, which may have the answer to my problem, but I am having trouble figuring out how to adapt to my code due to inexperience in Visual Basic.
I was able to get it to work for a single column of data, comparing one column of data from one sheet to another, but cannot get it to compare entire rows of data.
Here is an example of I want this to work:
Sheet 1 Sheet 2
Column 1 Column 2 Column 1 Column 2
Row 1 22a 33 11 11
Row 2 22a 33a 22a 33
Row 3 55 22b 55 23b
The code in the link will tell you what is not in sheet 1 but in sheet 2 and vice versa. In this example, I would like the code to tell me Sheet 1 Row 2 and Sheet 1 Row 3 are not in Sheet 2, and Sheet 2 Row 1 and Sheet 2 Row 3 are not in Sheet 1 (Sheet 1 Row 1 and Sheet 2 Row 2 match).
If that is ok by you, you can do it without VBA using the following formula:
={IF(IFERROR(MATCH(A1&"|"&B1;Sheet7!$A$1:$A$3&"|"&Sheet7!$B$1:$B$3;0);-1)=-1;"Unique";"")}
Assuming that each of your tables start in A1 (so that the tables with three entries span A1:B3), and entering this formula into C1 (and copying it down), press CTRL+SHIFT+ENTER when entering the formula to create an array formula, this will show the word "Unique" in column C if the pair in that row on that sheet is not in any of the row-pairs on sheet 2.
You can then use conditional formatting to highlight unique rows, filter on the tables to include only unique rows, or some other way of doing what you need.
NOTE 1: I have entered my numbers in Sheet6 and Sheet7 instead of 1 and 2. The formula written above goes into Sheet6.
NOTE 2: My language use ; instead of , as function separator, so if yours use , you need to change that.
NOTE 3: You will need to expand the ranges Sheet7!$A$1:$A$3 and Sheet7!$B$1:$B$3 if your set grows (this will happen automatically if new rows are inserted in between the old ones). The best is still probably to create named ranges for each of the 4 columns, exchange the references with those, and manage the named ranges instead of the formulas.
NOTE 4: If your data set contains the character "|", you need to change that as well, to match some character that you for sure do not have there.
Alternatively you could in column C on each cheet enter (assuming first entry in C1)
=A1&"|"&B1"
and copy this down, then run the solution from your copied example using that C column instead of on A1 and B1.

Vlookup or Match and Continuous Numbering

I am having a difficult time figuring this out and your help is greatly appreciated!
If there is the same name across multiple sheets, I would like the the number first assigned to them to populate and the remaining numbers to be in numerical order throughout the remaining sheets.
Below is sheet 1. C9 has a star near the name because it is a duplicate in sheet 2 (to follow)
Below is sheet 2. C9 is the duplicate name from sheet 1. I need the numbering for sheet 1 to remain as is and sheet 2 as 1, 8, 9, 10, 11, etc.
I am up for 2 options:
Manually enter 1 in cell B9. When I currently do this on sheet 2, the numbers start over again from 1 as opposed to the MAX number from sheet 1.
Automatically populate number when there is a name match. I have tried vlookup and match with my current formulas and they do not work with continuous numbering.
Below are my current formulas:
Cell B9, sheet 2
=MAX('Sheet 1'!B9:B66)+IF(ISTEXT(C9),1,"")
Cell B10:B66, sheet 2
=IF(ISTEXT(C10),IF(OR(ROW()=9,IF(ROW()=9,TRUE,MAX(INDIRECT("B9:B"&ROW()-1))=0)),MAX(INDIRECT("Sheet"&RIGHT(REPLACE(CELL("filename"),1,FIND("]",CELL("filename")),""),LEN(REPLACE(CELL("filename"),1,FIND("]",CELL("filename")),""))-5)*1-1&"!C:C"))+1,MAX(INDIRECT("B9:B"&ROW()-1))+1),"")
I really appreciate your time and help!!
Assuming B8 in Sheet2 is not numeric, names do not repeat within any one sheet and only two sheets are involved, I suggest in B9 of Sheet2 and copied down to suit:
=IFERROR(INDEX(Sheet1!B:B,MATCH(C9,Sheet1!C:C,0)),MAX(Sheet1!B:B,B$8:B8)+1)

Replace or recode several different values by a single value in an Excel file

I have an Excel worksheet which contains data in several columns. For a specific column, I will need Excel to replace all values between, say 10 to 15, by the value 1 and values between 16 and 20 by the value 2 and so forth.
I know how to do it for a single value; ie: I can replace value 10 by 1, 11 by 1 and so on. But this will be a tedious exercise. Are there some lines of codes that can execute this task?
Thanks for your help.
regards,
Ali
If you do not need to automate this with a macro or repeat often, you can do this quickly right on the spreadsheet.
Insert a new column to the right of the column to change. Let's say the column was A and you just created a new column B.
Enter the formula =INT(A1/5) - 1 in cell B1.
Copy this formula to all cells in column B for the extent of the cells in column A.
Copy the cells in column B and paste to column A using right-click, "Paste special...", Values, then click Ok.
Delete column B (this is a temporary/work column).
This will replace the values in column A with the adjusted values in column B. Proceed with any other columns.
Here's a quick and dirty way, that will have to be modified based on what values you really want to change to and from. This converts 11 to 15 to 1, and 16 to 20 to 2, etc.
You'll probably want to put a button on the spreadsheet, and then right click and choose "View Code". Then enter the following between the Sub and End Sub statement. "RangetoChange" is the name of a named range, OR you can put in the range itself, like "A1:A100". Once it's all entered, then you just get out of design mode (that you entered to place the button), then click the button. Make sure that you change the formula to what you really want the result to be.
Dim A() As Variant
Dim i As Integer
A = Range("RangetoChange")
For i = 1 To (UBound(A) - LBound(A) + 1)
A(i, 1) = (A(i, 1) \ 5) - 1
Next i
Range("RangetoChange") = A

Microsoft Excel – How to copy cells to a different worksheet on every nth row

Microsoft Excel – How to copy cells to a different worksheet on every nth row.
I have an interesting problem. It is probably simple, but I can’t figure it out.
I have a list of cells (about 10 columns across and over thousand rows, soon to be expanding)
A1-A10 and down
These are my headings and main input cells (let’s call this Summary Sheet)
I need these cells copied and preferably linked to the adjacent worksheet (Detailed Sheet), but in such a way that each cell (or 10 cell across) is copied on every 20 th line.
At times I will be adding and deleting rows from the Summary Sheet. Therefore I would love to be able to use autofill or some feature like that in the Detailed Sheet. After I update my Summary Sheet and could then update Detailed Sheet by autofilling the formulas down.
More detailed info:
Each row to which these cells are copied becomes a heading row for each 20 line module. The 19 rows below the copied headings remains empty and detailed calculations are done on the 19 rows further right. Each section is an identical module with many detailed calculations and the results on the 1 row in each module.
Presently I only use the Detailed Sheet and it is very time consuming to add or remove modules and their headings.
Summary Sheet
A B C D
1 #A1 #B1 #C1 …
2 #A2 #B2 #C2 …
3 #A3 #B3 #C3 …
Detailed Sheet
A B C D
1 #A1 #B1 #C1 …
… 19 empty lines
21 #A2 #B2 #C2 …
… 19 empty lines
31 #A3 #B3 #C3 …
… 19 empty lines
Thanks for any answers.
Martin
Place a button on your Summary sheet, and put this code behind it, changing the sheetnames and the button name to what you want to use. Then every time you want to redo the Detail lines, hit the button. Note: I've written this so the Summary sheet is Sheet2, and the Detail sheet is Sheet1:
Private Sub RedoDetailedSheet_Click()
Dim i As Integer, j As Integer
For i = 0 To Worksheets("Sheet2").UsedRange.Rows.Count - 1
For j = 1 To Worksheets("Sheet2").UsedRange.Columns.Count
Worksheets("Sheet1").Cells(20 * i + 1, j).Formula = "=Sheet2!" _
& Worksheets("Sheet2").Cells(i + 1, j).Address
Next j
Next i
End Sub
Here's the code based on your sample file for that specific situation. You'll need to change the format of the Model column to General.
Private Sub RedoDetailedSheet_Click()
Dim i As Integer, j As Integer
For i = 0 To Worksheets("Input").UsedRange.Rows.Count - 2
For j = 1 To Worksheets("Input").UsedRange.Columns.Count
Worksheets("Output").Cells(20 * i + 29, j + 2).Formula = "=Input!" _
& Worksheets("Input").Cells(i + 2, j).Address
Next j
Next i
End Sub
This is easily handled with Excel's Lookup functions - no VBA required - and that makes this more appropriately asked on https://superuser.com/.
Update: I couldn't get your file from MediaFire, but it appears from what you've written recently that Lance's code should work for you. Good luck.