Keeping Conditional Formatting - vba

Hi I'm busy with a VBA macro that copies data from one sheet to another, problem is whenever i paste the data to the other sheet, the conditional formatting falls off.It messes up with what i want to achieve. Isn't there a code I could use to keep conditional formatting. here is my code:
'In this example I am Copying the Data from Sheet1 (Source) to Sheet2
(Destination)
Sub sbCopyRangeToAnotherSheet()
'Method 1
Application.ScreenUpdating = False
'Set active sheet as current sheet
temp = ActiveSheet.Index
'Clear contents in sheet 1
Sheets("Sheet1").Select
Range("B22").Select
Range(Selection, Selection.End(xlToRight)).Select
Range(Selection, Selection.End(xlDown)).Select
Selection.ClearContents
'Clear Specials in Sheet 1
Range("B13").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.ClearContents
'Return to current sheet and copy required contents
Sheets(temp).Select
Range("D51").Select
Range(Selection, Selection.End(xlToRight)).Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
'Paste data in sheet 1
Worksheets("Sheet1").Activate
k = Worksheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row
Range("B22").Select ' kindly change the code to suit your paste location
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
'Copy specials over to sheet1
Sheets(temp).Select
Range("i36").Select
p = Range(Selection, Selection.End(xlDown)).Count
j = 0
For k = 1 To p
Sheets(temp).Select
t = Range("i36").Offset(k - 1, 0).Value
s = Range("j36").Offset(k - 1, 0).Value
If t = True Then
Sheets("Sheet1").Select
j = j + 1
Range("b13").Offset(j - 1, 0).Value = s
Else: End If
Next k
'Delete Empty Rows In UPL
Dim iRow As Long, lastRow As Long
Dim ws As Worksheet
Set ws = Worksheets("Sheet1") 'qualify your sheet
lastRow = ws.Range("A" & ws.Rows.Count).End(xlUp).Row 'find last used row
For iRow = lastRow To 1 Step -1 'run from last used row backwards to row 1
If ws.Cells(iRow, 3).Text = "#N/A" Or _
ws.Cells(iRow, 4).Text = "#N/A" Then
ws.Rows(iRow).Delete
End If
Next iRow
' Paste Unit Into UPL
Sheets(temp).Select
temp = Sheets(temp).Range("d35").Value
model = Range("D26").Value
Sheets("Sheet1").Select
Range("B11").Value = temp & " " & model
End Sub
Please Assist

so I recommend to replace this:
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
with this:
Selection.PasteSpecial Paste:=xlPasteAllMergingConditionalFormats, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False 'so that Excel will not be in the copy mode

Related

Copy data in one column to a different column on another sheet based on a third column's data

So, I'm very new to VBA and I am having a difficult time finding answers to what I believe should be a fairly straightforward question.
I have a workbook that has 2 sheets, which we will call Sheet1 and Sheet2.
I want to copy data from columns B, D and E on Sheet1 to the first available row in columns A, B and C on Sheet 2, with the following changes:
Sheet1 Sheet2
Col E Col A
Col D Col B
Col B Col C
But I only want the data to be copied if the cell value of each row in Sheet1 Column I is "Y".
I don't have any code for this yet.
UPDATE:
After taking advice from a response, I ran a Macro record and got this:
Sub VBlk()
'
' VBlk Macro
' V Block Copy
'
'
Range("B2").Select
Selection.Copy
Sheets("Sheet2").Select
Range("C3").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone,
SkipBlanks _
:=False, Transpose:=False
Range("B3").Select
Sheets("Sheet1").Select
Range("D2").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Sheet2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sheets("Sheet1").Select
Range("E2").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Sheet2").Select
Range("A3").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End Sub
Try the code below (Hope it helps) :
Sub test()
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Set ws1 = Sheets("sheet1")
Set ws2 = Sheets("sheet2")
'get the Last non empty row in sheet1 based on Column B
lastrow1 = ws1.Cells(Rows.Count, 2).End(xlUp).Row
For i = 1 To lastrow1
'get the Last non empty row in sheet2 based on Column A
lastrow2 = ws2.Cells(Rows.Count, 1).End(xlUp).Row
If ws1.Range("I" & i).Value = "Y" Then
ws2.Range("A" & lastrow2 + 1).Value = ws1.Range("E" & i)
ws2.Range("B" & lastrow2 + 1).Value = ws1.Range("D" & i)
ws2.Range("C" & lastrow2 + 1).Value = ws1.Range("B" & i)
End If
Next i
End Sub

Looping though only selected sheets to proceed several steps

I have an Excel file which contains several sheets where I have to cut-copy from one column to another.
When I use the code on one specific sheet it works perfectly, yet while I've already tried to use e.g. Sheets(Array("ThisSheet", "ThatSheet")).Select and it worked partially, because after row 131 it pastes the cut data in the wrong direction, which is odd. Nonetheless, no idea how to solve it.
Could you please help me with the code? I'd trupy appreciate it. In the comments you can find names of the specific columns only, so please simply ingore it.
Sub TABFixLoop_Main()
' TABFix Macro Loop Core Scratch
' === Declaces which tabs are in the loop ========
' === Exceptions: ES20, IT40, IT43, IT44, IT45, PT20 ===
Application.ScreenUpdating = False
Dim ws As Worksheet
Dim Sheets As Range
Set Sheets = Sheets(Array("BE00", "CH10", "CZ00", "DK00", "ES00", "FI00", "IT00", "LU30", "NL00", "NO00", "PT00", "SE00"))
For Each ws In Sheets
Do
' Fit the columns size
ws.Activate
ws.Columns.AutoFit
' Putting value ranges in correct places:
' MMDoc #
Range("P5").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Range("N5").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
ws.Columns("N:N").Select
Selection.NumberFormat = "0"
Range("P5").Select
Range(Selection, Selection.End(xlDown)).Select
Application.CutCopyMode = False
Selection.ClearContents
' Age
Range("Q5").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Range("O5").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
Range("Q5").Select
Range(Selection, Selection.End(xlDown)).Select
Application.CutCopyMode = False
Selection.ClearContents
' PO Vendor
Range("R5").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Cut
Application.CutCopyMode = False
Selection.Copy
Range("P5").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
Range("P5").NumberFormat = "0"
Range("R5").Select
Range(Selection, Selection.End(xlDown)).Select
Application.CutCopyMode = False
Selection.ClearContents
' Business Area
Range("S5").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Range("R5").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
Range("S5").Select
Range(Selection, Selection.End(xlDown)).Select
Application.CutCopyMode = False
Selection.ClearContents
' Remove empty columns
ws.Columns("S:T").Select
Selection.Delete Shift:=xlToLeft
' Add formula to count aging ranges
Range("U5").Select
ActiveCell.FormulaR1C1 = "=+IF(RC[-6]<=30,""0-30"",IF(RC[-6]<=60,""31-60"",IF(RC[-6]<=90,""61-90"",IF(RC[-6]<=120,""91-120"",IF(RC[-6]<=180,""121-180"",IF(RC[-6]<=365,""181-365"",IF(RC[-6]>365,"">365"","""")))))))"
Range(Selection, Selection.End(xlDown)).Select
Selection.FillDown
Loop Until ws = Sheets(Sheets.Count).Active
Application.ScreenUpdating = True
End Sub
Sub test()
Dim ws As Worksheet
For Each ws In Worksheets
Select Case ws.Name
Case "BE00", "CH10", "CZ00", "DK00", "ES00", "FI00", "IT00", "LU30", "NL00", "NO00", "PT00", "SE00"
ws.Columns.AutoFit
shiftdata ws, "P", "N"
shiftdata ws, "Q", "O"
shiftdata ws, "R", "P"
With ws.Range("U5")
.FormulaR1C1 = "=+IF(RC[-6]<=30,""0-30"",IF(RC[-6]<=60,""31-60"",IF(RC[-6]<=90,""61-90"",IF(RC[-6]<=120,""91-120"",IF(RC[-6]<=180,""121-180"",IF(RC[-6]<=365,""181-365"",IF(RC[-6]>365,"">365"","""")))))))"
.Copy Destination := ws.Range(.Address & ":" & .End(xlDown).Address)
End With
Case Else
End Select
Next ws
End Sub
Sub shiftdata(ws As Worksheet, strFrom As String, StrTo As String)
Dim r As Range
Set r = ws.Range(strFrom & "5:" & strFrom & ws.Range(strFrom & "5").End(xlDown).Row)
r.Copy
ws.Range(StrTo & "5").PasteSpecial xlPasteValues
r.ClearContents
End Sub

Code Cleanup for Combining Sheets

I do not have much experience with VBA but I will start by explaining my situation.
I have a workbook with 341 sheets. Each sheet is identical in layout in that they occupy the space A1:J48. I need to combine all of these into one sheet called "COMBINATION". The information of relevance is from A10:J48. I also need to have the cells from A1:J9 as they are the title which is shared across all the sheets.
What I did was write a code that copies A1:J48 for Sheet1 (to get the title and info) and pastes it into "COMBINATION" with the paste special as text, then a code that goes to Sheet2 and copies from A10:J48 and pastes it in the first empty cell in column A of "COMBINATION".
This brings me to my problem. I have realized that there must be an easier way of doing this instead of copying the code 339 more times for each of the sheets.
See below the code. It does what I want correctly but as mentioned, I would like to find a way to not do this 339 more times...
Sheets("Sheet1").Select
Range("A1:J48").Select
Selection.Copy
Sheets("COMBINATION").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Selection.Columns.AutoFit
Sheets("Sheet2").Select
Range("A10:J10").Select
Range("J10").Activate
Range(Selection, Selection.End(xlDown)).Select
Application.CutCopyMode = False
Selection.Copy
Sheets("COMBINATION").Select
NextFree = Range("A10:A" & Rows.Count).Cells.SpecialCells(xlCellTypeBlanks).Row
Range("A" & NextFree).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
I would use code like the following:
Dim ws As Worksheet
Dim r As Long
'Copy A1:J9 from the first sheet
Worksheets("Sheet1").Range("A1:J9").Copy
WorkSheets("COMBINATION").Range("A1").PasteSpecial Paste:=xlPasteValues, _
Operation:=xlNone, _
SkipBlanks:=False, _
Transpose:=False
'Now loop through every sheet (except "COMBINATION") copying cells A10:J48
r = 10 ' first sheet will be copied to row 10 in COMBINATION
For Each ws In Worksheets
If ws.Name <> "COMBINATION" Then
ws.Range("A10:J48").Copy
Worksheets("COMBINATION").Range("A" & r).PasteSpecial Paste:=xlPasteValues, _
Operation:=xlNone, _
SkipBlanks:=False, _
Transpose:=False
'Set pointer ready for next sheet
r = r + 39
End If
Next
'Set column widths
Worksheets("COMBINATION").Columns.AutoFit
If your sheets don't always have data in all 39 rows (10 to 48), replace r = r + 39 with
r = Worksheets("COMBINATION").Range("A" & Worksheets("COMBINATION").Rows.Count).End(xlUp).Row + 1
Put the repeating code into a loop (untested):
Dim i as Integer
For i=2 to 341
Sheets(i).Select
Range("A10:J10").Select
Range("J10").Activate
Range(Selection, Selection.End(xlDown)).Select
Application.CutCopyMode = False
Selection.Copy
Sheets("COMBINATION").Select
NextFree = Range("A10:A" & Rows.Count).Cells.SpecialCells(xlCellTypeBlanks).Row
Range("A" & NextFree).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Next i
Range.PasteSpecial xlPasteValues is convenient but slow. It is much faster to define your 'Target' range to be the same size as your source range and do a direct assignment.
Sub CombineData()
Application.ScreenUpdating = False
Dim ws As Worksheet
Dim Target As Range
With Worksheets("COMBINATION")
.Range("A1:J9").Value = Worksheets("Sheet1").Range("A1:J49").Value
For Each ws In Worksheets
If ws.Name <> .Name Then
Set Target = .Range("A" & .Rows.Count).End(xlUp).Offset(1)
Target.Resize(39, 10).Value = ws.Range("A10:J48").Value
End If
Next
End With
Application.ScreenUpdating = True
End Sub

Excel Macro - Repeat a process

I have a recorded macro, for a simple process in Excel. However, I need it to repeat the process for about 80 lines. Here is the code I have for the first 4 lines. Any help on a simple way to do this would be appreciated. Thank you.
Sub Macro2()
'
' Macro2 Macro
'
'
Range("A5").Select
ActiveCell.FormulaR1C1 = "1"
Sheets("EST COST").Select
Range("D6").Select
Selection.Copy
Sheets("IL").Select
Range("I5").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range("A5").Select
ActiveCell.FormulaR1C1 = "0"
Range("A6").Select
ActiveCell.FormulaR1C1 = "1"
Sheets("EST COST").Select
Range("D6").Select
Selection.Copy
Sheets("IL").Select
Range("I6").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range("A6").Select
ActiveCell.FormulaR1C1 = "0"
Range("A7").Select
ActiveCell.FormulaR1C1 = "1"
Sheets("EST COST").Select
Range("D6").Select
Selection.Copy
Sheets("IL").Select
Range("I7").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range("A7").Select
ActiveCell.FormulaR1C1 = "0"
End Sub
You want to use a for...next loop. Some Googling should get you quite far, but here's a flavour of the general idea:
dim startRow as integer
dim endRow as integer
dim myColumn as integer
startRow = 5
endRow = 45
For activeRow = startRow to endRow
[do something]
myColumn = [some column number]
cells(activeRow, myColumn).Value = [something]
Next activeRow
Something like this
Sub test()
Dim wsTarget As Worksheet
Dim wsSource As Worksheet
Set wsTarget = Sheets("EST COST")
Set wsSource = Sheets("IL")
Dim intIndex As Integer
For intIndex = 5 To 85
wsTarget.Range("A" & intIndex).FormulaR1C1 = "1"
wsTarget.Range("D" & intIndex).Copy
With wsSource
.Range("I" & intIndex).PasteSpecial Paste:=xlPasteValues _
, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
.Range("A" & intIndex).FormulaR1C1 = "0"
End With
Next
End Sub
To keep your code as similar as you have it, try this:
Sub test()
Dim rng As Range
Dim i&
For i = 5 To 40
' WHAT SHEET IS YOUR DEFAULT RANGES ON?
Range("A" & i).FormulaR1C1 = "1" ' what sheet is this on? We want to be explicit
Sheets("EST COST").Range("D" & i + 1).Copy
Sheets("IL").Range("I" & i).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range("A" & i).FormulaR1C1 = "0"
Next i
End Sub
I'm assuming you want the pasted range to be offset one row (you copy A5, pasted into I6). As I noted though, I'd prefer to know what sheet your ranges to be copied are on, so we can add that worksheet to the ranges (Range("A"& i)... should really be Sheets("mainSheet").Range("A"&i)...)

"if instr" not working with a loop

I am a VBA beginner. I am trying to build a macro that would copy and paste (value) an entire row to a new sheet based on a differentiation criteria. The differentiation criteria, in this case, would be the content of specific cell. In other words, if the cell contains the word "Caviar" then copy the row into sheet 1 otherwise copy into sheet 2. The following macro works when I run it manually (row one by one).
Sub Search_and_copy()
Dim rng As String
rng = Sheets("40").Range("F11").Value
Dim rowNo As Integer
rowNo = 6
Dim celltxt As String
celltxt = Sheets("40").Range("P11").Value
rowNo = 6
If Sheets("40").Range("F11").Value = "254" Then
If InStr(celltxt, "CAVIAR") Then
Rows("11:11").Select
Selection.Copy
Sheets("Sheet1").Select
If IsEmpty(Cells(rowNo, 1)) Then
Sheets("Sheet1").Cells(rowNo, 1).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
Else: Do Until IsEmpty(Cells(rowNo, 1))
rowNo = rowNo + 1
Loop
Sheets("Sheet1").Cells(rowNo, 1).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
End If
Sheets("40").Select
Application.CutCopyMode = False
Selection.Delete Shift:=xlUp
Else
Rows("11:11").Select
Selection.Copy
Sheets("Sheet2").Select
If IsEmpty(Cells(rowNo, 1)) Then
Sheets("Sheet2").Cells(rowNo, 1).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
Else: Do Until IsEmpty(Cells(rowNo, 1))
rowNo = rowNo + 1
Loop
Sheets("Sheet2").Cells(rowNo, 1).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
End If
Sheets("40").Select
Application.CutCopyMode = False
Selection.Delete Shift:=xlUp
End If
End If
End Sub
However, as soon as I introduce a loop (see code below), the differentiation is no longer properly made and all rows are copied into the same worksheet. What am I doing wrong?
Sub Search_and_copy()
Dim rng As String
rng = Sheets("40").Range("F11").Value
Dim rowNo As Integer
rowNo = 6
Dim celltxt As String
celltxt = Sheets("40").Range("P11").Value
Do Until IsEmpty(Sheets("40").Range("F11").Value)
rowNo = 6
If Sheets("40").Range("F11").Value = "254" Then
If InStr(celltxt, "CAVIAR") Then
Rows("11:11").Select
Selection.Copy
Sheets("Sheet1").Select
If IsEmpty(Cells(rowNo, 1)) Then
Sheets("Sheet1").Cells(rowNo, 1).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
Else: Do Until IsEmpty(Cells(rowNo, 1))
rowNo = rowNo + 1
Loop
Sheets("Sheet1").Cells(rowNo, 1).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
End If
Sheets("40").Select
Application.CutCopyMode = False
Selection.Delete Shift:=xlUp
Else
Rows("11:11").Select
Selection.Copy
Sheets("Sheet2").Select
If IsEmpty(Cells(rowNo, 1)) Then
Sheets("Sheet2").Cells(rowNo, 1).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
Else: Do Until IsEmpty(Cells(rowNo, 1))
rowNo = rowNo + 1
Loop
Sheets("Sheet2").Cells(rowNo, 1).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
End If
Sheets("40").Select
Application.CutCopyMode = False
Selection.Delete Shift:=xlUp
End If
End If
Loop
End Sub
The (first) problem is that you never change the value of celltxt inside your loop. After you read Sheets("40").Range("P11").Value into the string, you never change it. This means that InStr(celltxt, "CAVIAR") will always be the same until the Sub ends. All you should need to do is update it inside your loop.
One other thing to do while you're at it is to apply a little DRY and extract your common code into a function. The only difference between your If and Else is the sheet name. Try something like this:
Sub Search_and_copy()
Dim celltxt As String
Do Until IsEmpty(Sheets("40").Range("F11").Value)
celltxt = Sheets("40").Range("P11").Value
If Sheets("40").Range("F11").Value = "254" Then
If InStr(celltxt, "CAVIAR") Then
DontRepeatYourself "Sheet1"
Else
DontRepeatYourself "Sheet2"
End If
End If
Loop
End Sub
Private Sub DontRepeatYourself(sheet As String)
Dim rowNo As Long
rowNo = 6
Rows("11:11").Select
Selection.Copy
Sheets(sheet).Select
Do Until IsEmpty(Cells(rowNo, 1))
rowNo = rowNo + 1
Loop
Sheets(sheet).Cells(rowNo, 1).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Sheets("40").Select
Application.CutCopyMode = False
Selection.Delete Shift:=xlUp
End Sub