Copy columns based on set paramaters - vba

I am copying information from one workbook to another. The code I have so far works great if every column has data. It does not work when I am trying to repeatedly copy information from column A and B of worksheet(supplementary expenses) to worksheet(expenses) and column B is blank. As the next time the sub is run and Column B does have values they are placed in the next blank cell, not the cell that is correlated to column A.
Here is the code I have so far:
Sub SupplementaryExpenses()
Dim x As Workbook
Dim y As Workbook
Set y = Workbooks.Open("File Path")
Set x = Workbooks.Open("File Path")
x.Sheets("b.1 Supplementary expenses").Range("a9", Range("a9").End(xlDown)).Copy
y.Sheets("Expenses").Range("a1").End(xlDown).Offset(1, 0).PasteSpecial xlPasteValues
x.Sheets("b.1 Supplementary expenses").Range("b9", Range("b9").End(xlDown)).Copy
y.Sheets("Expenses").Range("b1").End(xlDown).Offset(1, 0).PasteSpecial xlPasteValues
x.Sheets("b.1 Supplementary expenses").Range("c9", Range("c9").End(xlDown)).Copy
y.Sheets("Expenses").Range("c1").End(xlDown).Offset(1, 0).PasteSpecial xlPasteValues
Also any time this sub is run it would be helpful if there were someway to fill column L with the flag 201601 and then change to 201602 when I bring in the next months data.

Try this:
Sub SupplementaryExpenses()
Dim x As Workbook
Dim y As Workbook
Dim lastrow As Long
Dim tRow as long
Set y = Workbooks.Open("File Path")
Set x = Workbooks.Open("File Path")
With x.Sheets("b.1 Supplementary expenses")
lastrow = .Range("A" & .Rows.Count).End(xlUp).Row
tRow = y.Sheets("Expenses").Range("a1").End(xlDown).Offset(1, 0).Row
y.Sheets("Expenses").Range("A" & trow).Resize(lastrow - 8, 3).Value = .Range(.Cells(9, 1), .Cells(lastrow, 3)).Value
y.Sheets("Expenses").Range("D" & trow).Resize(lastrow - 8, 1).Value = .Range(.Cells(9, 8), .Cells(lastrow, 8)).Value
End With
End Sub
It will take all of the three columns at once and assign the values to the new area. It will not care about blanks in column B or C.
This should be faster than copy/paste as you only want the values.

Get the last used row and change out your range statements similar to this:
Dim LastRow
LastRow = Cells.Find(What:="*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
x.Sheets("b.1 Supplementary expenses").Range(Cells(9, 1), Cells(LastRow, a)).Copy 'this is R1C1 format meaning row then column
You can use this for filling a column
If you put it after the rest of your code and ensure that you have the sheet you want column L populated with active:
sDate = Format(Date, "yyyymm")
For i = 2 To LastRow' you may need to grab this anew if you added lines
If Cells(i, "L") = vbNullString Then 'ensures that there isn't anything in the cell
Cells(i, "L").value = sDate
End If
Next

Related

Cutting and Pasting Cells in Excel VBA

The Function of the program is to find the first row that has an empty cell, next to that cell is a number that needs to be cut and pasted in the previous row on column 26.
-I am trying to run a loop that goes through the entire sheet and deletes the row once copied and pasted.
-If there is already data inside it will skip it and continue on.
-The Second Method is my most promising but I just can't seem to find out how to run the format of Cells(x,1)
(Method One)
Dim x As Integer
x = 1
this = x - 1
rowdelete = x
If Cells(x, 1) = "" Then
Cells(x, 1).Select.Cut
Cells(x - 1, 26).PasteSpecial
Rows([rowdelete]).EntireRow.Delete
End If
(Method Two)
Dim x As Integer
x = 1
this = x - 1
rowdelete = x
If Cells(x, 1) = "" Then
Cells(x, 1).Select.Cut
Cells(x - 1, 26).PasteSpecial
Rows([rowdelete]).EntireRow.Delete
End If
I don't know if i'm just missing something but your Method1 and Method2 look identical to me. I think your issue was that you were trying to paste to Row 0 which doesn't exist. It's also good practice to define all your ranges and cells or excel will take whatever is active at the time.
Try the below code that loops through blank cells in Col A and doesn't use the Clipboard which should make things much faster for you.
Sub LoopThroughBlanks()
Dim wbk As Workbook
Dim ws As Worksheet
Dim lRow As Long
Dim Cell As Range
Set wbk = ActiveWorkbook
Set ws = wbk.Worksheets("Sheet1") 'Be sure to change this to your worksheet name!
With ws
'Find last row of data in worksheet
lRow = .Cells.Find(What:="*", _
After:=.Cells(1, 1), _
LookIn:=xlFormulas, _
LookAt:=xlPart, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
'Loop through blank cells in col a
For Each Cell In .Range("A1:A" & lRow).SpecialCells(xlCellTypeBlanks)
If Cell.Row = 1 Then
.Range("A1").EntireRow.Insert
End If
'Copy to column 26
Cell.Offset(-1, 25).Value = Cell.Offset(0, 1).Value
.Rows(Cell.Row).EntireRow.Delete
Next Cell
End With
End Sub

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

Copy and Paste dynamic ranges to new sheet in Excel with VBA

I am new to macro writing and I need some help.
I have one sheet and need to copy the columns and reorder them to paste into a software program.
I want to copy A2 - the last data entry in column A and paste it into A1 on Sheet2
I want to copy B2 - the last data entry in column A and paste it into K1 on Sheet2
I want to copy C2 - the last data entry in column A and paste it into C1 on Sheet2
I want to copy D2 - the last data entry in column A and paste it into D1 on Sheet2
Then from Sheet 2, I want to copy A1:KXXXX (to the last entry in column A) and save it on the clipboard to paste into the other application
Here is my code, I have tried... (I know this is just for copying column A, but I got stuck there.)
Sub Copy()
aLastRow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row
Range("A2" & aLastRow).Select
Selection.Copy
Sheets("Sheet2").Select
Range("A1").Select
ActiveSheet.Paste
End Sub
Thank you so much for your help!
Jess
Try this instead. Given that you said you got an error with the paste code and I am still using that, I think you'll still have an error there. Post the error message. Hopefully we can figure that out.
Sub copyStuff()
Dim wsIn As Worksheet
Set wsIn = Application.Worksheets("Sheet1")
Dim endRow As Long
wsIn.Activate
endRow = wsIn.Cells(wsIn.Rows.Count, "A").End(xlUp).Row
Dim r As Range
Dim wsOut As Worksheet
Set wsOut = Application.Worksheets("Sheet2")
' column a to column a
Set r = wsIn.Range(Cells(2, 1), Cells(endRow, 1))
r.Copy
wsOut.Range("A1").PasteSpecial xlPasteAll
' column b to column k
Set r = wsIn.Range(Cells(2, 2), Cells(endRow, 2))
r.Copy
wsOut.Range("K1").PasteSpecial xlPasteAll
' column c to column c
Set r = wsIn.Range(Cells(2, 3), Cells(endRow, 3))
r.Copy
wsOut.Range("C1").PasteSpecial xlPasteAll
' column d to column d
Set r = wsIn.Range(Cells(2, 4), Cells(endRow, 4))
r.Copy
wsOut.Range("D1").PasteSpecial xlPasteAll
' Copy data from sheet 2 into clipboard
wsOut.Activate
Set r = wsOut.Range(Cells(1, 1), Cells(endRow - 1, 11))
r.Copy
End Sub
My original answer is below here. You can disregard.
This should accomplish your first goal:
Sub copyStuff()
Dim wsIn As Worksheet
Set wsIn = Application.Worksheets("Sheet1")
Dim endRow As Long
endRow = wsIn.Cells(wsIn.Rows.Count, "A").End(xlUp).Row
Dim r As range
Set r = wsIn.range(Cells(2, 1), Cells(endRow, 4))
r.Copy
Dim wsOut As Worksheet
Set wsOut = Application.Worksheets("Sheet2")
wsOut.range("A1").PasteSpecial xlPasteAll
End Sub
I copied all 4 columns at once since that would be much faster but it assumes the columns are the same length. If that isn't true you would need to copy one at a time.
The data should be in the clipboard at the end of the macro.
Edit: I removed "wsIn.Activate" since it isn't really needed.
Edit 2: Oops! I just noticed you wanted the output in different columns. I'll work on it.
Generally you want to avoid .Select and .Paste when copying values and rather copy by .value = .value:
Sub Copy()
Dim aLastRow As Long
Dim clipboard As MSForms.DataObject
Set clipboard = New MSForms.DataObject
aLastRow = Sheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row
Sheets("Sheet2").Range("A1:A" & aLastRow - 1).Value = Sheets("Sheet1").Range("A2:A" & aLastRow).Value
Sheets("Sheet2").Range("K1:K" & aLastRow - 1).Value = Sheets("Sheet1").Range("B2:B" & aLastRow).Value
Sheets("Sheet2").Range("C1:D" & aLastRow - 1).Value = Sheets("Sheet1").Range("C2:D" & aLastRow).Value
clipboard.SetText Sheets("Sheet2").Range("A1:K" & aLastRow - 1).Value
clipboard.PutInClipboard
End Sub

how to copy and paste from multiple columns in vba

I'm trying to copy data from columns C,D,J,P when the value in column I is "O"
I'm very new at VBA and the best approach I could think of what to use an IF statement, but I haven't been able to paste more than two consecutive columns.
sub firsttry
Dim bodata As Worksheet
Dim bopresentation As Worksheet
Set bodata = Worksheets("BO Data")
Set bopresentation = Worksheets("BO presentation")
bodata.Activate
Dim i As Integer
i = 1
For i = 1 To 20
If bodata.Cells(i, 9).Value = "O" Then
bodata.Range(Cells(i, 3), Cells(i, 4)).Copy
bopresentation.Range("b20").End(xlUp).Offset(1, 0).PasteSpecial (xlPasteAll)
Else
End if
Next
end sub
Range doesn't work like that: try this:
For i = 1 To 20
If bodata.Cells(i, 9).Value = "O" Then
Application.Union(bodata.Cells(i, 3), bodata.Cells(i, 4), _
bodata.Cells(i, 10), bodata.Cells(i, 16)).Copy
bopresentation.Range("b20").End(xlUp).Offset(1, 0).PasteSpecial (xlPasteAll)
End if
Next
Your approach itself is exactly right. Looping over a range of cells is usually the most efficient way of handling data. In your current code you'd simply need to repeat the copy for the cells missing inside the loop.
In VBA, however, "pasting" in a seperate line of code if rarely necessary. It is also good coding practise to define all your variables at the top of your code.
Here is different approach using the For each-loop and summing up the wanted range with the Union method:
Dim rCell as Range
Dim rSource as Range
'Define the source range as the entire column C
With ThisWorkbook.Worksheets("BO Data")
Set rSource = .Range("C1", .Cells(Rows.Count, 3).End(xlUp))
End with
'Loop over each cell in the source range and check for its value
For each rCell in rSource
If rCell.Value = "0" Then
'If requirement met copy defined cells to target location
With ThisWorkbook.Worksheets("BO Data")
Application.Union(.Cells(rCell.Row, 3), _
.Cells(rCell.Row, 4), _
.Cells(rCell.Row, 10), _
.Cells(rCell.Row, 16) _
).Copy Destination = ThisWorkbook.Worksheets("BO Presentation").Range("B2")
End With
Next rCell
This, of course, loops over all cells in Column C. If you want to limit the range, you can simply adjust rSource to your needs.

Copying and pasting datas to the selected row

I have a code piece from my working code which copies and pastes datas from other Worksheets to one masterworkbooks mastersheet. The code below lets me copy and paste datas from column BX to column A's first empty row and does the same for column CC to column B's first empty row. However, I would like to paste the column CC to Column B's (10th) row. How can I do this?
lRow = copySheet.Cells(copySheet.Rows.Count, 1).End(xlUp).Row
With copySheet.Range("BX2:BX" & lRow)
pasteSheet.Cells(Rows.Count, "A").End(xlUp).Offset(1, 0)
.Resize(.Rows.Count, .Columns.Count) = .Value
End With
'Determine last row of Column B in copySheet
lRow = copySheet.Cells(copySheet.Rows.Count, 1).End(xlUp).Row
With copySheet.Range("CC2:CC" & lRow)
pasteSheet.Cells(Rows.Count, "B").End(xlUp).Offset(1, 0)
.Resize(.Rows.Count, .Columns.Count) = .Value
End With
Could you show me how I can determine how many rows are seletected to be copied?
Edit: Now I would like to add an if condition for another column, which should say:
if
column U in Worksheet "data" has cell value "8636" then these values
should be pasted to Column H in Worksheet "KomKo"(pastesheet); to the
next row as I used the code above in the "with" part.
Else( If the value in Column H is not 8636) then it should paste the
value inside this column to Column G at Worksheet "KomKo"(pastesheet)
with same preferences as above again
.
How can I do this ?
Change pasteSheet.Cells(Rows.Count, "B").End(xlUp).Offset(1, 0).Resize(.Rows.Count, .Columns.Count) = .Value to that pasteSheet.Range("B10").Resize(.Rows.Count, .Columns.Count) = .Value
************* ANSWER TO QUESTION EDIT ****************
******* Added maxR - highest last row from column H and G *******
You could do something like this to get what you need:
Sub check8636values()
Dim copySheet, pasteSheet As Worksheet
Dim lRowU, lRowH, lRowG, maxR, i As Long
'Dont forget to change to the correct sheet names!!!!
Set copySheet = ThisWorkbook.Sheets("data")
Set pasteSheet = ThisWorkbook.Sheets("KomKo")
lRowU = copySheet.Cells(copySheet.Rows.Count, "U").End(xlUp).Row
For i = 1 To lRowU
lRowG = pasteSheet.Cells(pasteSheet.Rows.Count, "G").End(xlUp).Row + 1
lRowH = pasteSheet.Cells(pasteSheet.Rows.Count, "H").End(xlUp).Row + 1
maxR = Application.Max(lRowG,lRowH)
If copySheet.Cells(i, "U").Value = "8636" Then
pasteSheet.Cells(maxR, "H").Value = copySheet.Cells(i, "U").Value
pasteSheet.Cells(maxR, "Y").Value = copySheet.Cells(i, "T").Value
Else
pasteSheet.Cells(maxR, "G").Value = copySheet.Cells(i, "U").Value
pasteSheet.Cells(maxR, "X").Value = copySheet.Cells(i, "T").Value
End If
Next i
End Sub
since you're dealing with one-column ranges only there's no need for the With-End With blocks to abbreviate the Resize method parameters: just use lRow for the first one only
moreover since you're not showing if copySheet and pasteSheet are from the same workbook it's safer to reference them before .Rows.Count, and prevent issue deriving from their source workbook excel version
'Determine last row of Column B in copySheet
lRow = copySheet.Cells(copySheet.Rows.Count, 1).End(xlUp).Row
pasteSheet.Cells(pasteSheet.Rows.Count, "A").End(xlUp).Offset(1, 0).Resize(lRow) = copySheet.Range("BX2:BX" & lRow).Value
pasteSheet.Range("B10").Resize(lRow).Value = copySheet.Range("CC2:CC" & lRow).Value