Maintaining destination data format when copying style in VBA? - vba

I am trying to copy the style from a specific column (formatted as Text starting from its second row) to another column (formatted as Date starting from its second row). Both columns stores values.
I am able to copy-and-paste the style to the destination column:
.Columns("A").Copy '# "A" is the starting column
.Columns(dest_col).PasteSpecial Paste:=xlPasteFormats '# dest_col is the destination column
but this code also formats it as a Text column, while I want to keep its original formatting (i.e. Date starting from the second row).
Is there any option I can use to prevent this behavior?

You may try to take only the values of the specific parameters, which you are interested in (E.g., style, Interior Color, Font Color etc.)
The following works only when the whole column has the same format, as far as I did not to loop through every cell:
Option Explicit
Sub TestMe()
Dim colFrom As Long
Dim colTo As Long
colFrom = 1
colTo = 5
CopyFullFontAndInterior colFrom, colTo
End Sub
Sub CopyFullFontAndInterior(colFrom As Long, colTo As Long, Optional wsN As Long = 1)
Dim copyFrom As Range
Dim copyTo As Range
With Worksheets(1)
Set copyFrom = .Range(.Cells(1, colFrom), .Cells(2 ^ 20, colFrom))
Set copyTo = .Range(.Cells(1, colTo), .Cells(2 ^ 20, colTo))
End With
copyTo.Style = copyFrom.Style
If copyFrom.Interior.Color > 0 Then copyTo.Interior.Color = copyFrom.Interior.Color
If copyFrom.Font.Color > 0 Then copyTo.Font.Color = copyFrom.Font.Color
End Sub
A possible workaround is to save the format of a given cell of the column in a variable and to use it after the .PasteSpecial:
Sub TestMe()
Dim saveOurFormat As String
saveOurFormat = Columns(5).Cells(2).NumberFormat
Columns("A").Copy
Columns(5).PasteSpecial Paste:=xlPasteFormats
Columns(5).NumberFormat = saveOurFormat
Application.CutCopyMode = False
End Sub

Related

Conditional formatting in Excel using VBA

I am extremely new to VBA world and need some assistance with the VBA side of conditional formatting.
I need conditional formatting to be applied TO COLUMN (B4-B71),(D4-D71),(F4-F71),(H4-H71),(J4-J71),(L4-L71),(N4-N71),(P4-P71),(R4-R71) WHICH SATISFY a CONDITION AS BELOW.
Examplw, valid for H4 cell
=$H$4=XLOOKUP($H$4;$U$13:$U$1146;$V$13:$V$1146)THEN CHANGE TO YELLOW COLOR.
tHERE WILL BE NAMES IN THE EVERY CELL IN THE ABOVE COLUMNS AND EVERY CELL WILL CHECK THE INFORMATION IN THE COLUMN (U13-U1146).För exampl, IF THE iNFORMATIONS in cell H4 matches with the information in u column then H4 will be highlighted. the same will be applied to all the cells for above mentioned column.
and the code will be valid for apx.31 sheets in the workbook, will contain same information and same kind of conditional formatting.
Below code creates a public sub that defines the conditional formatting rules.
Function funcApplyContitionalFormatting applies the specified rules from mentioned Sub.
Public Sub condFormat(ws as Worksheet, startCol as Long, startRow as Long, fRow As Long, formattingRule as String, interiorColor as Long, fontColor as Long)
Dim rng As Range
Set rng = ws.Range(ws.Cells(startRow , startCol), ws.Cells(fRow, startCol))
rng.FormatConditions.Delete
rng.FormatConditions.Add Type:=xlExpression, Formula1:= _
formatRule
rng.FormatConditions(rng.FormatConditions.Count).SetFirstPriority
rng.FormatConditions(1).Font.Color = fontColor
rng.FormatConditions(1).Interior.Color = interiorColor
End Sub
Here are the function that applies the formatting rule above (also using a table/listobject to get the final row with data in that table):
Public Function funcApplyConditionalFormatting()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Sheet1")
Dim lo As ListObject
Set lo = ws.ListObjects("yourTable")
fRow = lo.DataBodyRange.Rows.Count
Application.ScreenUpdating = False
'Call functions
condFormat(ws, 4, 3, fRow, "YourFormulaHere", 65535, 65535)
Application.ScreenUpdating = True
End Function
You'd need to change inputs to suit your specific requirements, but this works for general formatting with VBA.

Copy values from Range and paste each one with different given (row) offset in another sheet

First of all I would like to introduce myself. Iam Miguel and I recently started to learn VBA in order to improve and save time at work. I am familiar with formulas, all types, but when turning to VBA I get sometimes stuck.
I am trying to loop the range A2:A355 from Sheet"Aux" and copy each value to sheet "CS", and each value shall be pasted in Column A:A, but with the offset given in range B2:B355 Sheet "Aux". For Example I give the example attached.
Sample Code:
This is the code:
Sub cablexsection()
Dim s As Integer
Dim smax As Integer
smax = Sheets("Aux").Range("b1").Value
Sheets("CS").Activate
For s = 3 To smax
Sheets("CS").Cells(s, 1).Value = Sheets("Aux").Cells(s, 1).Value
'here I have to set the offset to down in order to paste cells given Sheets("Aux").Cells(s, 2) values
Next s
End Sub
And under the link you can find the file to be worked in:
Original File
Thank you very much and sorry if this question is repeated. I have tried to look through the forum but maybe I do not know what to write exactly.
Try this
Option Explicit
Sub CableXsection()
Dim wsAux As Worksheet, wsCS As Worksheet
Dim s As Long, sMax As Long, offSetCell As Range
Set wsAux = ThisWorkbook.Worksheets("Aux")
Set wsCS = ThisWorkbook.Worksheets("CS")
sMax = wsAux.Range("B1").Value
Application.ScreenUpdating = False
For s = 3 To sMax
Set offSetCell = wsAux.Cells(s, 2) '2 is the offset column from the same row
If Not IsError(offSetCell) And IsNumeric(offSetCell) Then
wsCS.Cells(offSetCell.Value2 + s, 1).Value = wsAux.Cells(s, 1).Value
End If
Next
Application.ScreenUpdating = True
End Sub

Using the value of the last row of a column as a range?

I have a vba code that determines the date based on 3 cells in excel, it then reformats the date.
Sub Test()
Dim i As Long
i = Sheet1.Cells(Rows.Count, 2).End(xlUp).Row
Range("K3").Formula = "=DATE(A3,G3,H3)"
Range("K3").AutoFill Destination:=Range("K3:K28")
Set fmt = Range("K3:K28")
fmt.NumberFormat = "ddmmmyyyy"
End Sub
The line that gives a value to "i" (which is 28) determines the last populated cell in that column.
I would like to use the value of "i" as K28 in the range.
I am fairly new to VBA and have not been able to figure out how to accomplish this task.
You can slightly simplify your code. There is no need to use AutoFill:
Sub Test()
Dim i As Long
With Sheet1
i = .Cells(.Rows.Count, 2).End(xlUp).Row
With .Range("K3:K" & i)
.Formula = "=DATE(A3,G3,H3)"
.NumberFormat = "ddmmmyyyy"
End With
End With
End Sub

reading a range value from a cell

in the following code
Sub SetColorScheme(cht As Chart, i As Long)
Dim y_off As Long, rngColors As Range
Dim x As Long
y_off = i Mod 10
'this is the range of cells which has the colors you want to apply
Set rngColors = ThisWorkbook.Sheets("colors").Range("A1:C1").Offset(y_off, 0)
With cht.SeriesCollection(1)
'loop though the points and apply the
'corresponding fill color from the cell
For x = 1 To .Points.Count
.Points(x).Format.Fill.ForeColor.RGB = _
rngColors.Cells(x).Interior.Color
Next x
End With
End Sub
the range from which the data are read is in th emoment stated in the code. Is there a chance that it is read from asheet in the worksheet? So that a person can enter A1:C1 and it will place it the way it is in the code in the moment?
I'm not sure how you want to handle the user's input, but of course the range can be an incoming variable. I have it below as a string but elegance would be the range object. Sorry if this is too simple, I'm not sure your question.
Sub SetColorScheme(UserRange As String, cht As Chart, i As Long)
...
'this is the range of cells which has the colors you want to apply
Set rngColors = ThisWorkbook.Sheets("colors").Range(UserRange).Offset(y_off, 0)
...
End Sub
If the user enters "A1:C1" in cell D1 then you can make use of this range with:
Set rngColors = ThisWorkbook.Sheets("colors").Range(Range("D1").Value).Offset(y_off, 0)
' but you should refer to the w/sheet as well
Set rngColors = ThisWorkbook.Sheets("colors") _
.Range(ThisWorkbook.Sheets("colors").Range("D1").Value).Offset(y_off, 0)
Range("D1").Value obtains the text "A1:C1" which is then used to identify this Range.

How to compare two columns in different sheets

I have one excel file with multiple sheets.
I need to compare two sheets (1) TotalList and (2) cList with more than 25 columns, in these two sheets columns are same.
On cList the starting row is 3
On TotalList the starting row is 5
Now, I have to compare the E & F columns from cList, with TotalList E & F columns, if it is not found then add the entire row at the end of TotalList sheet and highlight with Yellow.
Public Function compare()
Dim LoopRang As Range
Dim FoundRang As Range
Dim ColNam
Dim TotRows As Long
LeaData = "Shhet2"
ConsolData = "Sheet1"
TotRows = Worksheets(LeaData).Range("D65536").End(xlUp).Row
TotRows1 = Worksheets(ConsolData).Range("D65536").End(xlUp).Row
'TotRows = ThisWorkbook.Sheets(LeaData).UsedRange.Rows.Count
ColNam = "$F$3:$F" & TotRows
ColNam1 = "$F$5:$F" & TotRows1
For Each LoopRang In Sheets(LeaData).Range(ColNam)
Set FoundRang = Sheets(ConsolData).Range(ColNam1).Find(LoopRang, lookat:=xlWhole)
For Each FoundRang In Sheets(ConsolData).Range(ColNam1)
If FoundRang & FoundRang.Offset(0, -1) <> LoopRang & LoopRang.Offset(0, -1) Then
TotRows = Worksheets(ConsolData).Range("D65536").End(xlUp).Row
ThisWorkbook.Worksheets(LeaData).Rows(LoopRang.Row).Copy ThisWorkbook.Worksheets(ConsolData).Rows(TotRows + 1)
ThisWorkbook.Worksheets(ConsolData).Rows(TotRows + 1).Interior.Color = vbYellow
GoTo NextLine
End If
Next FoundRang
NextLine:
Next LoopRang
End Function
Please help with the VBA code.
Thanks in advance...
First I am going to give some general coding hints:
set Option Explicit ON. This is done through Tools > Options >
Editor (tab) > Require Variable Declaration . Now you HAVE to
declare all variables before you use them.
always declare a variables type when you declare it. If you are unsure about what to sue or if it can take different types (not advisable!!) use Variable.
Use a standard naming convention for all your variables. Mine is a string starts with str and a double with dbl a range with r, etc.. So strTest, dblProfit and rOriginal. Also give your variables MEANINGFUL names!
Give your Excel spreadsheets meanigful names or captions (caption is what you see in excel, name is the name you can directly refer to in VBA). Avoid using the caption, but refer to the name instead, as users can change the caption easily but the name only if they open the VBA window.
Ok so here is how a comparison between two tables can be done with your code as starting point:
Option Explicit
Public Function Compare()
Dim rOriginal As Range 'row records in the lookup sheet (cList = Sheet2)
Dim rFind As Range 'row record in the target sheet (TotalList = Sheet1)
Dim rTableOriginal As Range 'row records in the lookup sheet (cList = Sheet2)
Dim rTableFind As Range 'row record in the target sheet (TotalList = Sheet1)
Dim shOriginal As Worksheet
Dim shFind As Worksheet
Dim booFound As Boolean
'Initiate all used objects and variables
Set shOriginal = ThisWorkbook.Sheets("Sheet2")
Set shFind = ThisWorkbook.Sheets("Sheet1")
Set rTableOriginal = shOriginal.Range(shOriginal.Rows(3), shOriginal.Rows(shOriginal.Rows.Count).End(xlUp))
Set rTableFind = shFind.Range(shFind.Rows(5), shFind.Rows(shFind.Rows.Count).End(xlUp))
booFound = False
For Each rOriginal In rTableOriginal.Rows
booFound = False
For Each rFind In rTableFind.Rows
'Check if the E and F column contain the same information
If rOriginal.Cells(1, 5) = rFind.Cells(1, 5) And rOriginal.Cells(1, 6) = rFind.Cells(1, 6) Then
'The record is found so we can search for the next one
booFound = True
GoTo FindNextOriginal 'Alternatively use Exit For
End If
Next rFind
'In case the code is extended I always use a boolean and an If statement to make sure we cannot
'by accident end up in this copy-paste-apply_yellow part!!
If Not booFound Then
'If not found then copy form the Original sheet ...
rOriginal.Copy
'... paste on the Find sheet and apply the Yellow interior color
With rTableFind.Rows(rTableFind.Rows.Count + 1)
.PasteSpecial
.Interior.Color = vbYellow
End With
'Extend the range so we add another record at the bottom again
Set rTableFind = shFind.Range(rTableFind, rTableFind.Rows(rTableFind.Rows.Count + 1))
End If
FindNextOriginal:
Next rOriginal
End Function