Macro for selecting from multiple columns - vba

I need help on macros in Excel. I have a table in Excel (example attached).
I need columns A, E and G from source sheet, after last row i need A,E and H , after last row A,E and I and so on. Means Column A and E will be constant, only third column will change until column K.
In vertical manner.
Source data:
A B C D E F G H I J K
NAME AGE CITY STATE COUNTRY CODE PART DUEDATE VEND COMM QTY
Target:
A E G
A E H
A E I
A E J
A E K
EDIT: Code I am trying:
Sub Mosaic()
With ws
'Get the last row and last column
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
lCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
End With
With ws2
'Get the last row and last column
lRow2 = .Range("A" & .Rows.Count).End(xlUp).Row
lCol2 = .Cells(1, .Columns.Count).End(xlToLeft).Column
End With
'Save the range from A1:Alastrow and E1:Elastrow and store as variable
Set aRng = ws.Range("A1" & lRow)
Set aRng2 = ws.Range("E1" & lRow)
'Union(AE range and G1:Glastrow)
Set gRng = ws.Range("G1" & lRow)
Set hRng = ws.Range("H1" & lRow)
Set uRng = Union(aRng, aRng2, gRng)
uRng.Copy
ws2.Range("A" & lRow2).PasteSpecial
End Sub

Finding last rows: Excel VBA select range at last row and column
Find the last row of data on source sheet and store as variable.
Save the range from A1:Alastrow and E1:Elastrow and store as variable (since we need it three times)
Union(AE range and G1:Glastrow)
Copy / Paste
Union(AE range and H1:Hlastrow)
Copy
Find destination last row
Paste destination last row + 1
Repeat for all I, J, and K
You can write your own code from the help file provided
Edit: The fix for your code:
Sub Mosaic()
Dim aRng, eRng, extraRng as Range
Dim lRow, lRow2, CurCol as Long
With ws
'Get the last row and last column
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
End With
'Save the range from A1:Alastrow and E1:Elastrow and store as variable
Set aRng = ws.Range("A1:A" & lRow)
Set aRng2 = ws.Range("E1:E" & lRow)
For CurCol = 7 to 11 'Cols G (7) to K (11)
Set extraRng = ws.Range(Cells(2, CurCol),Cells(lRow, CurCol))
'Always get the lRow2 right before pasting to ensure you have the last row.
'Get the last row of destination sheet
lRow2 = ws2.Range("A" & ws2.Rows.Count).End(xlUp).Row + 1
aRng.Copy
ws2.Range("A" & lRow2).PasteSpecial
eRng.Copy
ws2.Range("B" & lRow2).PasteSpecial
extraRng.Copy
ws2.Range("C" & lRow2).PasteSpecial
Next CurCol
End Sub

Related

VBA Subtotal(9,"range") based on another column value

I would like to use some macro to populate cells with the formula subtotal(9,"range"), being the range dinamic, based on the lenght of the cell.
sample
I need to populate in row "C" the formula subtotal(9;range) based on the values in column "B".
It have to check the value on column B, and compare to the row below. If the value of the row below is equal or inferior, it must be "blank", if not, will create a formula =subtotal(9,range), the range will start the row below and go until find a lenght equal or inferior.
I do this manual, but sometimes i have more than 1000 rows.
Many thanks.
In the question you mention to populate the row with the subtotal function only if current row is inferior or equal to next row, but in your sample you only populate when is inferior. So I coded it that way. It can be changed by replacing the > in If .Range("B" & next_row) > .Range("B" & r) Then to >=
Sub populate()
Dim r As Long, r2 As Long, last_row As Long
Dim next_row As Long, current_len As Long, test_len As Long
Dim rng As String
With ActiveSheet
last_row = .Cells(Rows.Count, 1).End(xlUp).Row
For r = 2 To last_row
next_row = r + 1
If .Range("B" & next_row) > .Range("B" & r) Then
current_len = .Range("B" & r)
'create range
For r2 = r + 1 To last_row
test_len = .Range("B" & r2)
If current_len >= test_len Then
rng = "C" & r + 1 & ":" & "C" & r2 - 1
Exit For
End If
Next
.Range("C" & r).Formula = "=SUBTOTAL(9," & rng & ")"
End If
Next
End With
End Sub

Delete Blank Rows from Column B

I am trying delete all rows where column B to AD (Lastrow) are blank. On my excel sheet every couple of rows or so column B to AD are blank so i am trying to delete those rows. I have been trying to use the below code:
Sub T()
Dim rng As Range
Set rng = Range("B1:AC10402")
rng.SpecialCells(xlCellTypeBlanks).EntireRow.Delete
End Sub
No success
Try this code:
Sub DeleteBlankRows()
Dim i As Long
Dim lastRow As Long: lastRow = 10 'here you have to specify last row your table uses
For i = lastRow To 1 Step -1
If Cells(i, Columns.Count).End(xlToLeft).Column = 1 Then
Rows(i).Delete
End If
Next i
End Sub
Little explanation
You specified that you need check for emptiness within row, columns B through AD. This piece of code Cells(i, Columns.Count).End(xlToLeft).Column will return column of the right-most (starting from first column), non-empty cell. If whole row is empty or there's data in first column - it will return 1 - which is misleading, when you are considering A cloumn. But it isn't here, since we consider columns starting with B. So if it returns 1, it means that the row is empty and should be deleted.
this deletes all blank rows in column B
Dim LastRow, i As Integer
LastRow = activesheet.Cells(activesheet.Rows.Count, "A").End(xlUp).Row
For i = LastRow To 1 Step -1
If WorksheetFunction.CountA(Range("B" & i)) = 0 Then
Range("B" & i).EntireRow.Delete
End If
Next i
this deletes all blank rows if column B to column AC is blank
Dim LastRow, i As Integer
LastRow = activesheet.Cells(activesheet.Rows.Count, "A").End(xlUp).Row
For i = LastRow To 1 Step -1
If WorksheetFunction.CountA(Range("B" & i & ":" & "AC" & i)) = 0 Then
Range("B" & i & ":" & "AC" & i).EntireRow.Delete
End If
Next i

Looping and finding similar number in VBA

I am very new to VBA. Just started reading it up 2 days ago. I am wondering how could I write a VB codes assigned to a button to read through the whole column and search for similar numbers.
After that identifying similar numbers, it would need to move on to another column to check if the character in the column are same too.
If both of the logic = true . How can i change the cell of the value of another column?
Sample data
For the current example. The code should know that the first column had matching numbers. After that it will check for the name which is "a" in the example. After that it will automatically change the point to 1 and 0. If there are 3 same ones it will be 1,0,0 for the point
You may try recording whatever you want to do with record macros first, then filter out the codes that are not necessary. If you do not know how to record it using macros, click on the link below. You can learn from the recorded macros and slowly improvise your codes in the future from the experience you may gain.
Here's [a link] (http://www.dummies.com/software/microsoft-office/excel/how-to-record-a-macro-in-excel-2016/)
As per image attached in image I am assuming numbers are in Column A, column to check characters is Column J and result needs to be displayed in Column O then try following code.
Sub Demo()
Dim dict1 As Object
Dim ws As Worksheet
Dim cel As Range, fCell As Range
Dim lastRow As Long, temp As Long
Dim c1
Set dict1 = CreateObject("Scripting.Dictionary")
Set ws = ThisWorkbook.Sheets("Sheet2") 'change Sheet2 to your data sheet
With ws
lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row 'last row with data in Column A
c1 = .Range("A2:A" & lastRow)
For i = UBound(c1, 1) To 1 Step -1 'enter unique values with corresponding values in dict1
dict1(c1(i, 1)) = .Range("J" & i + 1) '+1 for Row 2
Next i
Set fCell = .Range("A2")
For Each cel In .Range("A2:A" & lastRow) 'loop through each cell in Column A
temp = WorksheetFunction.CountIf(.Range(fCell, cel.Address), cel) 'get count
If temp > 1 Then
If cel.Offset(0, 9) = dict1(cel.Value) Then
cel.Offset(0, 14).Value = 0
Else
cel.Offset(0, 14).Value = 1
End If
Else
cel.Offset(0, 14).Value = 1
End If
Next cel
End With
End Sub
EDIT
Sub Demo()
Dim ws As Worksheet
Dim lastRow As Long
Application.ScreenUpdating = False
Set ws = ThisWorkbook.Sheets("Sheet2") 'change Sheet3 to your data range
With ws
lastRow = .Cells(.Rows.count, "A").End(xlUp).Row 'last row with data in Column A
.Range("O2").Formula = "=IF(MOD(SUMPRODUCT(($A$2:$A2=A2)*($J$2:$J2=J2)),3)=1,1,0)" 'enter formula in Cell O2
.Range("O2").AutoFill Destination:=.Range("O2:O" & lastRow) 'drag formula down
.Range("O2:O" & lastRow).Value = .Range("O2:O" & lastRow).Value 'keep only values
End With
Application.ScreenUpdating = True
End Sub

Defining dynamic range

1) I have a sheet named C.A.
I want to copy the range starting from B$3 to the last cell (which is of column H)
2) Then paste it to another sheet called 2017
To 2 cells below the (last cell of column B containing data)
I did the second one, but, cant define the first one.
Dim lastRow As String
lastRow = ActiveSheet.Cells(Rows.Count, "B").End(xlUp).Row + 2
Range("B" & lastRow).Select
Selection.PasteSpecial
End Sub
Try this:
Dim ws_ca As Worksheet
Dim ws_17 As Worksheet
Dim nr_2017 As Long
Dim nr_ca As Long
Set ws_ca = ThisWorkbook.Worksheets("C.A.")
Set ws_17 = ThisWorkbook.Worksheets("2017")
nr_ca = ws_ca.Cells(Rows.Count, 8).End(xlUp).Row
nr_2017 = ws_17.Cells(Rows.Count, 2).End(xlUp).Row
ws_17.Range("B" & nr_2017 + 3 & ":H" & nr_2017 + nr_ca).Value = ws_ca.Range("B3:H" & nr_ca).Value

Copy data from one worksheet to other based on condition

I am trying to copy data from one worksheet to another blank worksheet in a workbook. It has three columns where in I want to search a specific 'Unit' value and just copy all of the records with similar 'Unit' values into second worksheet with similar column structure.
**Doc_number** **Doc_version** **Unit**
43449 01 D013-LAG R
43450 02 D013-LAG R
43451 01 D013-DAMP
43452 02 D013-DAMP
Output should be like this if I provide D013-LAG R as input value ;
**Doc_number** **Doc_version** **Unit**
43449 01 D013-LAG R
43450 02 D013-LAG R
I want to paste the selected column to the DELIVERY sheet like if I pass 'Unit' value as 'D03-LAG R' then the output in the DELIVERY file should be just like as follows;
Doc_version Unit
01 D013-LAG R
02 D013-LAG R
It's more like I want to select entire row and then paste the data to another worksheet to the columns I want to. I don't want entire row to be pasted as it is.
I don't have much experience in VBA and have already tried doing the code which results in copying of the last record encountered in the loop. Need your advice.
Sub Row_Copy()
Dim sheet1 As Worksheet, sheet2 As Worksheet
Dim i As Integer, k As Integer
Dim Sheet1LR As Long, Sheet2LR As Long
Set sheet1 = Sheets("MASTER")
Set sheet2 = Sheets("DELIVERY")
Sheet1LR = Sheet1.Range("A" & Rows.Count).End(xlUp).Row + 1
Sheet2LR = Sheet2.Range("A" & Rows.Count).End(xlUp).Row + 1
i = 2
k = Sheet2LR
Do Until i = Sheet1LR
If Trim(sheet1.Cells(i, 26).Value) = "D013-LAG R" Then
With sheet1
.Range(.Cells(i, 1), .Cells(i, 26)).Copy
End With
With sheet2
.Cells(k, 1).PasteSpecial
.Cells(k, 1).Offset(1, 0).PasteSpecial
End With
End If
k = k + 1
i = i + 1
Loop
MsgBox (Complete)
ActiveWorkbook.Save
Application.ScreenUpdating = False
End Sub
This is the latest code I am using;
Sub CommandButton1_Click()
Dim LSearchRow As Long
Dim LCopyToRow As Long
Dim CopyFromSht As Worksheet
Dim CopyToSht As Worksheet
Dim LCnt As Long
On Error GoTo Err_Execute
Set CopyFromSht = Workbooks("TestRow.xlsm").Sheets("MASTER")
Set CopyToSht = Workbooks("TestRow.xlsm").Sheets("DELIVERY")
With CopyFromSht
'Start search in row 4
LSearchRow = .Range("A" & Rows.Count).End(xlUp).Row
'Start copying data to row 2 in Sheet2 (row counter variable)
LCopyToRow = 2
For LCnt = 2 To LSearchRow
'If value in column Z = "Unit as needed", copy entire row to Sheet2
If .Range("Z" & LCnt).Value = "D013-LAG R" Then
'Select row in Sheet1 to copy
.Rows(LCnt).Copy Destination:=CopyToSht.Rows(LCopyToRow)
'Move counter to next row
LCopyToRow = LCopyToRow + 1
End If
Next LCnt
End With
I wrote a macro that might give you an idea how to resolve your problem:
Sub CopyRows()
' Variables
Dim row_src As Integer
Dim row_dest As Integer
' Inizialize row within destination sheet
row_dest = 1
' Loop over all rows in source sheet
For row_src = 1 To 32767
' Go to correct cell within source sheet
Sheets("Source").Select
Range("B" & CStr(row_src)).Select
' Done if this row is empty
If (ActiveCell.Value = "") Then
Exit For
End If
' Copy row if it's the header or if match found
If (row_src = 1) Or (ActiveCell.Value = "D013-LAG R") Then
' Copy source row
Rows(CStr(row_src) & ":" & CStr(row_src)).Select
Selection.Copy
' Go to destination row
Sheets("Destination").Select
Rows(CStr(row_dest) & ":" & CStr(row_dest)).Select
' Copy row
ActiveSheet.Paste
' Make sure next row is copied on the right place
row_dest = row_dest + 1
End If
Next
End Sub
In case you want to copy only a few columns from the source to the destination sheet, try this:
' Copy columns B to E of source row
Range("B" & CStr(row_src) & ":E" & CStr(row_src)).Select
Selection.Copy
' Go to destination
Sheets("Destination").Select
Range("B" & CStr(row_dest)).Select
' Copy these columns
ActiveSheet.Paste
In case the columns to be copied are not consecutive (for instance B, D and F):
Range("B" & CStr(row_src) & ",D" & CStr(row_src) & ",F" & CStr(row_src)).Select
Range("F" & CStr(row_src)).Activate
Selection.Copy
By the way, I don't know this all by heart.
You can easily find out the details by executing within Excel:
- Menu View/Macro/Register Macro (or something similar; I got the Italian version)
- Do manually anything you want to automate
- Menu View/Macro/Interrput registration
- Menu View/Macro/View/Modify
I hope this helps you