EXCEL > how to refresh a cell to apply new cell format? - vba

I have a value in a cell, say 123456789.12345. By default excel shows this as 123456789.1. I need to see all digits after comma, so I change cell format to custom > #
To apply this change I need to refresh the cell, for example select it and press F2, then Enter. But how to apply this refresh for a column or a range?
No VBA if possible please.

You can speed up the process doing this:
NO VBA OPTION
Select the column and go to the Data ribbon and click Text to Columns.
Choose Delimited and click Next.
Uncheck all the delimiters and click Next.
Select the text option and press Finish
:
The number formatting of all the cells will update.
This trick is a bit of a hack, but it works. What it does is take all the values from each row and then re-enters them into the cells automatically. For this reason, this trick will not work for cells that are formulas. If you have formulas, pressing F9 should recalculate the sheet and update the number format. But in my experience, I haven’t had this problem with formulas.
VBA OPTION
Just create a VBA with this code:
Sub Oval1_Click()
Dim i As Integer
i = 1
Do Until Cells(i, 1) = 0
Cells(i, 1).NumberFormat = "#"
Cells(i, 1).Select
SendKeys "{F2}", True
SendKeys "{ENTER}", True
i = i + 1
Loop
End Sub
Have in mind that for this to work, you will need a "button" with the name Oval1_click, or just add the code to the button you create.
Explain:!
1: First we start the code on button click
Sub Oval1_Click()
Then we declare a variable that is going to be used as the incremental value for the cell row.
Dim i As Integer
i = 1
We start the loop in the row 1, column 1 (a) that translate in A1, only if the value is not equal to 0.
Do Until Cells(i, 1) = 0
We assign the # format to the selected row (A1)
Cells(i, 1).NumberFormat = "#"
We select, press F2, and press Enter, to that row (A1)
Cells(i, 1).Select
SendKeys "{F2}", True
SendKeys "{ENTER}", True
We increment i value so it can change rows
i = i + 1
We finish the loop and the code if we get to an empty cell in that column
Loop
End Sub
And thats it.

Format the first cell the way you wanted.
Copy the cell with the correct format.
Select the other cells.
Right mouse button -> Paste Special (or Ctrl+Alt+ V).
Select the Format RadioBox.
Click Ok button.
Press Enter.

Select the cells in one column and set the new format
Go to Data --> Text To Columns and press Finish
That should refresh the selected cells and apply the new format.

Sub ForceAsText()
Dim cel As Range
Dim selectedRange As Range
Set selectedRange = Application.Selection
For Each MyCell In selectedRange.Cells
MyCell.NumberFormat = "#"
If MyCell.HasFormula Then
Dim Val As String
Val = MyCell.Formula
MyCell.Value = Val
End If
Next MyCell
End Sub

Related

VBA Excel Format Range when value is found

I'm trying to implement a macro that looks for the words "TRUE" and "FALSE" in a huge array of data - and then, when found, changes the color of the cells above it.
Specifically, I would like it to color not the TRUE/FALSE-cell, but the 30 cells directly above it. This is where things get tricky... I hope someone can help.
I've tried adapting the below code, but mostly I'm adding it as inspiration at this point.
Sub ChangeColor()
lRow = Range("C" & Rows.Count).End(xlUp).Row
Set MR = Range("C2:C" & lRow)
For Each cell In MR
Select Case cell.Value
Case "Yes"
cell_colour = 4
Case "y"
cell_colour = 4
Case Else
cell_colour = 3
End Select
cell.Interior.ColorIndex = cell_colour
Next
End Sub
Using a datafield array
Looping through a range is always time consuming; this should speed it up.
Caveat: Formatting single cells can maximize file size, so at least I reformat the whole column C to xlColorIndexNone.
Option Explicit
Public Sub Mark30CellsAbove()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("MySheet")
Dim v As Variant
Dim i As Long, j As Long, n As Long, m As Long, r As Long
Dim Rng As Range
Dim t As Double
' stop watch
t = Timer
' get last row in column C
n = ws.Range("C" & ws.Rows.Count).End(xlUp).Row
' get values to one based 2dim array
v = ws.Range("C1:C" & n).Value
' clear existing colors over the WHOLE column to minimize file size
ws.Range("C:C").Interior.ColorIndex = xlColorIndexNone
' loop through C2:Cn and mark 30 rows before found condition
For i = 2 To n
' check condition, find string "true" or "false"
If InStr(".true.false.", "." & LCase(v(i, 1)) & ".") > 0 Then
' set range block - fixed rows count 30 above found cell
If i < 32 Then ' only in case of less than 30 rows
Set rng = ws.Range("C2:C" & (i - 1))
Else
Set rng = ws.Range("C" & (i - 30) & ":C" & (i - 1))
End If
rng.Interior.ColorIndex = 4
End If
Next i
MsgBox "Time needed: " & Format(Timer - t, "0.00") & " seconds."
End Sub
Of course you could also loop within If - EndIf, just to see this slower method:
If InStr(".true.false.", "." & LCase(v(i, 1)) & ".") > 0 Then
' Always avoid to loop through a range
' For j = i - 1 To i - 30 Step -1
' If j < 2 Then Exit For ' optional escape if one line under title row
' ws.Cells(j, 3).Interior.ColorIndex = 4
' Next
End If
The code that I posted should only highlight cells in column B whose value is different from the corresponding cell in column A. I tested it and it worked OK.
If you want to try conditional formatting:
Select column B, or the part of column B that you want to colour conditionally.
In the following, I will assume that B1 is the active cell within the selection.
On the Home tab of the ribbon, click Conditional Formatting > New Rule...
Select "Use a formula to determine which cells to format".
Enter the formula =B1<>A1
If the active cell is not in row 1, adjust the formula accordingly. For example, if the active cell within the selection is B3, use =B3<>A3
Click Format...
Activate the Fill tab.
Select the desired fill colour.
Click OK until all dialogs have closed.
Change some values in column A and/or B to see the result.
Refer - https://social.technet.microsoft.com/Forums/ie/en-US/2fffa4d8-bbba-473b-9346-5fce8f0728a8/using-vba-to-change-a-cell-colour-based-on-the-information-in-a-different-cell-excel-2010?forum=excel
First you need to check whether the row of the cell is higher than 30 and then it you can offset to change the color:
Thus instead of this line: cell.Interior.ColorIndex = cell_colour
write this:
If cell.Row > 30 Then cell.Offset(-30, 0).Interior.ColorIndex = cell_colour
This may be done without VBA. You should set up two conditional formatting with formulas. First:
=COUNTIF(OFFSET(INDIRECT(ADDRESS(ROW(), COLUMN())),1,0,29,1), "TRUE")>0
and the same for false. To highlight the cell you just need to use Highlight Cell Rules (the top option for CF).
I would do this with conditional formatting
Mark all your data and press "Conditional Formatting". Enter 2 rules with Use a formula...
First rule is for TRUE. Assuming that you start with Col A:
=COUNTIF(A2:A31;TRUE)
The second rule is similar, just exchange TRUE by FALSE. Below the formula, press the "Format" button to set the color.
Explanation:
I reverted the logic: Instead of searching for TRUE/FALSE and then format the cells above, I look for every cell if it has at least one entry TRUE resp. FALSE in the next 30 cells. However, I have to admit I don't know how fast Excel can handle such a large amount of data.

Change Highlight Color After User input in Excel vba

I have a piece of code that will allow me to find the next free cell in column F, where an operator will input a Weight.
I wanted to help by highlighting the cells in a range close to where the input needs to be done (this can help to check that the entry is correct without filtering).
I can do that with the code below but I'm trying to remove the highlighting after the cell is written and I'm failing. I tried an approach with 'Do Until' but was also not satisfactory. The code runs but it does not remove the highlight once the user adds a value.
I have also tried using Wait functions but they freeze Excel completely (I cannot modify any value). Additionally, when I run in debug and use a random iteration to modify the Cell value, my code works.
'Find the last non-blank cell in column F (aka, column 6)
' We will add i rows to make the ith blank (in the for loop)
PreFree = Cells(Rows.Count, 6).End(xlUp).Row
NextFree = PreFree + 1
' Select Cell for manual input
Range("F" & NextFree).Select
'Do Until emptyWeight = False
If ThisWorkbook.Sheets("Input").Range("F" & NextFree) = "" Then
emptyWeight = True
Range(Cells(NextFree, "C"), Cells(NextFree, "F")).Interior.Color = RGB(181, 244, 0)
Else
Range(Cells(NextFree, "C"), Cells(NextFree, "F")).Interior.Color = RGB(255, 255, 255)
emptyWeight = False
End If
As Sir BruceWayne said, you can do this with Worksheet_Change event.
Private Sub Worksheet_Change(ByVal Target As Range)
' Declare and prepare the intersection & union of ranges
Dim rIntersect As Range
Set rIntersect = Intersect(Target.Offset(1, 0), Sheets("YourSheet").Range("F:F"))
' Exit this event if there is no change in column f
If rIntersect Is Nothing Then Exit Sub
' Include TargetCell
Set rIntersect = Union(Target, rIntersect)
' Declare the 'each range', in case the user will paste values into column f
Dim rEach As Range
' Will loop through each cell that made a change in column f
For Each rEach In rIntersect
' Give default color.
rEach.Interior.Color = RGB(255, 255, 255)
' And test if the value <blank>, sets color if it is true.
If rEach.Value = "" Then rEach.Interior.Color = RGB(181, 244, 0)
Next
End Sub
Hope this works for you. Good luck!
To OP, paste your code here

VBA Userform dropdown menu execution

I currently have this code which allows me to launch the userform, input the an item in the text box, auto populate the date, and select from a drop down menu
then paste that information into a new row.
The cbm (combo-box) item draws its values from a separate dynamically expanding table and is a drop down menu on the userform. The date is auto populated based on todays date and the text box is draws its value from whatever the user enters.
Private Sub btnSubmit_Click()
Dim ssheet As Worksheet
Set ssheet = ThisWorkbook.Sheets("InputSheet")
nr = ssheet.Cells(Rows.Count, 1).End(xlUp).Row + 1
ssheet.Cells(nr, 3) = CDate(Me.tbDate)
ssheet.Cells(nr, 2) = Me.cmblistitem
ssheet.Cells(nr, 1) = Me.tbTicker
My goal here is, depending on what list item is selected I want the name of that item to be pasted in a column that corresponds to that item. i.e if the user selects "apples" and the 3rd column is the "apple" column, I want it to paste in that location.
I am assuming this has to be down with some type of "if" statement.
Any help is appreciated.
Here is pic of my worksheet
supposing I correctly made my guessings, try this code
Option Explicit
Private Sub btnSubmit_Click()
Dim f As Range
If Me.cmblistitem.ListIndex = -1 Then Exit Sub '<--| exit if no itemlist has been selected
If Len(Me.tbTicker) = 0 Then Exit Sub '<--| exit if no item has been input
With ThisWorkbook.Sheets("InputSheet")
Set f = .Rows(1).Find(what:=Me.cmblistitem.Value, lookat:=xlWhole, LookIn:=xlValues, MatchCase:=False) '<--| look for proper column header
If f Is Nothing Then Exit Sub '<--| if no header found then exit
With .Cells(.Cells(Rows.Count, "A").End(xlUp).Row + 1, f.Column) '<--| refer to header column cell corresponding to the first empty one in column "A"
.Resize(, 3) = Array(Me.tbTicker.Value, Me.cmblistitem.Value, CDate(Me.tbDate)) '<--| write in one shot
End With
End With
End Sub
it's commented so you can easily change columns references as per your needs
BTW as for the combobox filling you may want to adopt the following code:
Dim cell As Range
With Me
For Each cell In [myName]
.cmblistitem.AddItem cell
Next cell
End With
which is optimized having referenced Me once before entering the loop so that it's being kept throughout it without further memory accesses

How do I put VLOOKUP in a cell and paste it down?

I'm using VlookUp in VBA, but it only works for one cell.
For Each MyCell In Selection
MyCell = application.WorksheetFunction.VlookUp(Range("C2"), Range("A2:B50000"), 2 , 0)
Next
I want to set a VlookUp in a cell, then roll this to all other cells. But I am only able to put the formula in the first cell, then a double click to others.
Try this instead:
With Selection
.FormulaR1C1 = "=VLOOKUP(RC3,R2C1:R50000C2,2,FALSE)"
.Value = .Value '// Comment out if you don't want to paste values.
End With
This enters the VLOOKUP() formula into each cell using a relative reference for the lookup value's row and then effectively pastes values to replace the formula.
If you really want you can use VBA syntax:
For Each myCell In Selection
myCell.Value = WorksheetFunction.Vlookup(Cells(myCell.Row, 3), Range("A2:B50000"), 2, False)
Next

vba how to check if a cell has no formatting or color

I recently had a question regarding how to copy a cell value into all cells below it and stop based on when column A got to a blank cell. post
The excel sheet I'm working in has many divider rows that are color filled across the entire row to separate categories as you scroll down the sheet. I would like to be able to skip these separating rows in column A when the macro checks for a blank cell in column A. Or I would like to just assign StopRow to the first cell which has no formatting/no color/no value.
Here is what I have, thanks to Ripster earlier today, but I've failed incorporating a proper if then statement with what he came up with.
Sub Example()
Dim MasterValue As String
Dim StopRow As Long
Dim i As Long
'Get the master value
MasterValue = Range("C5").Value
'Get the first blank cell in column A
StopRow = Range("A1").End(xlDown).Row
'Start at row 6 and continue to the "Stop Row"
For i = 6 To StopRow
'Set every cell from row 6 in column 3 to the "Master Value"
Cells(i, 3).Value = MasterValue
Next
End Sub
Please help.
Thanks
This took me a while but I found solution to your problem ;)
If macro goes to cell with different color - checking and do nothin, next "i" is taken. This should do what u want. It's possible to add more color ;)
Link to colors - http://dmcritchie.mvps.org/excel/colors.htm
Sub Example()
For i = 6 To 1200
If Cells(i, 3).Interior.ColorIndex = 1 Then 'here is color black
Else
If IsEmpty(Cells(i, 1)) = True Then 'if cells in column "A" is empty then stop
Exit For
Else
Cells(i, 3).Value = Range("C5").Value
End If
End If
Next i
End Sub
Your conditions for StopRow aren't clear. Do you want to set StopRow when the cell has a conditional formatting rule or simply when it has a different format than the default ? A cell may have a rule but it may not be applied. Anyway, the function presented here is something you might find of use.
Copy the ActiveCondition function somewhere in a module and then change your for loop like so:
For i = 6 To StopRow
If ActiveCondition(Cells(i,3))=0 Then StopRow=i : Exit For
Cells(i, 3).Value = MasterValue
Next
If you want to check for change in font color that didn't come from conditional formatting then you'd need an extra line:
For i = 6 To StopRow
If ActiveCondition(Cells(i,3))=0 Then StopRow=i : Exit For
If Cells(1,3).Font.ColorIndex=0 Then StopRow=i : Exit For
Cells(i, 3).Value = MasterValue
Next
There are more elegant ways to do this but this solution is the easiest to implement in your code.
Hope this helps.