Blink shape depending on cell value - vba

I'm trying to create a excel file where I will have shapes.
That shapes i'm trying to connect to cell values.
So when I click on button start, excel will go through the cell values, of cell value is X, I want shape X to blink red, and if cell value is Y cell will be green.
For now i programmed code for going through cells in one column and changing its color to green and red:
Sub test()
Dim sh As Shape
Dim area As String
Set sh = Sheet1.Shapes("X")
Range("A1").Select
Do Until ActiveCell.Value = ""
area = ActiveCell.Value
If area = "X" Then
sh.Fill.ForeColor.RGB = rgbRed
End If
ActiveCell.Offset(1, 0).Select
Loop End Sub
I have a problem with programming the code to change the name of cell and to change the color of other shapes.

You have to wait about 1 second between the selection of the cells in order to make it work. With your code and using Select Cell, something like this should work:
Sub test()
Dim sh As Shape
Dim area As String
Set sh = ActiveSheet.Shapes("X")
Range("A1").Select
Do Until ActiveCell.Value = ""
area = ActiveCell.Value
If area = "X" Then
sh.Fill.ForeColor.RGB = rgbRed
Application.Wait Now + #12:00:01 AM#
ElseIf area = "Y" Then
sh.Fill.ForeColor.RGB = rgbGreen
Application.Wait Now + #12:00:01 AM#
End If
ActiveCell.Offset(1, 0).Select
Loop
End Sub
In general, using Select in VBA is considered a bad practice, but in this case it makes the "application" look better, because you can follow the current cell.

Related

Getting a copied formula from the clipboard in Excel VBA

I’ve a routine that effectively pastes a link to a cell or cells that a user has copied to the clipboard, putting a space after the "=" (a personal preference, for readability) and changing the anchoring to row-only before pasting. If the link is to another sheet, the font is changed to blue. The code is as follows:
Sub QuickLink2()
' Copies a link,putting a space after the "=" and changing the
' anchoring to row-only. If the link is to another sheet, the
' font is changed to blue.
Dim r As Long, c As Long
Dim FormulaArr() As Variant
Dim Destination As Range
Application.ScreenUpdating = False
' Paste link
On Error Resume Next
ActiveSheet.Paste Link:=True
If Err.Number = 1004 Then GoTo NoSelection '1004 is a paste failure
On Error GoTo 0
' Transfer pasted link to array
If Selection.Cells.Count = 1 Then
ReDim FormulaArr(1 To 1, 1 To 1)
FormulaArr(1, 1) = Selection.Formula
Else
FormulaArr = Selection.Formula
End If
' Adjust formula spaces and anchoring
For r = 1 To UBound(FormulaArr, 1)
For c = 1 To UBound(FormulaArr, 2)
FormulaArr(r, c) = Replace(FormulaArr(r, c), "=", "= ")
FormulaArr(r, c) = Application.ConvertFormula _
(FormulaArr(r, c), xlA1, xlA1, xlAbsRowRelColumn)
Next c
Next r
Set Destination = Selection
Destination.Formula = FormulaArr
' Change font to blue if link is to another sheet
If Destination(1).Formula Like "*!*" Then _
Destination.Font.Color = RGB(0, 0, 255)
Exit Sub
NoSelection:
Application.CutCopyMode = False
End Sub
The idea here is to speed up the code by assigning the pasted link to a variant array, doing the necessary work on the array, and then assigning the array to a range. What I really want to do, however, is to access the copied cell formulas directly from the clipboard, and assign to the variant array without the intermediate ActiveSheet.Paste Link:=True step.
The following code would allow me to get the copied cell value, but of course I'm looking for the copied formulas.
Dim DataObj As New MSForms.DataObject
Dim S As String
DataObj.GetFromClipboard
S = DataObj.GetText
To get formula's:
Private Sub PutCellFormulaInClipBoard(ByVal Cell As Range)
Dim oDataObject As Object
Set oDataObject = _
GetObject("New:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
With oDataObject
.Clear
.SetText Cell.Cells(1).Formula
.PutInClipboard
End With
End Sub
Ref

How to write a VB script to find multiple keywords within all cells and highlight each keyword?

I'm currently having a list of keywords (e.g. CFO, CTO, interim manager, etc.) and I want to have a macro assigned to a button that can search all cells in Column E of Sheet 1 which contain these keywords then give back the result as well as highlight the keyword in the cell.
Each keyword is in a separate cell in Column A of Sheet 2.
If there is one keyword in the list, it will search for one but if there are more, it will search for combination.
Here is the screenshot to illustrate what I've describe above
I have found something over the Internet with suggestion to use AutoFilter but I can only use it to perform a search for one keyword. This is what I've tried:
Sub EmailFilter()
Application.ScreenUpdating = False
With Worksheets("Sheet1").Columns("E:E")
.AutoFilter Field:=1, Criteria1:= _
"=*" & Worksheets("Sheet2").Range("A2:A10") & "*", Operator:=xlAnd
End With
Application.ScreenUpdating = True
End Sub
Thanks in advance.
The below code will color all the matches with the same color(I have chosen blue). You can write this macro in a module and then create a Form Control Button and assign the macro to the button.
Sub macro()
Dim a As Integer, x As String, mystring As String
a = 2
Sheets("Sheet2").Activate
Cells(a, 1).Activate
Do While ActiveCell.Value <> ""
x = ActiveCell.Value
p = Len(x)
Application.GoTo Sheet1.Range("E2")
Do While ActiveCell.Value <> ""
mystring = ActiveCell.Value
If InStr(mystring, x) > 0 Then
Position = InStr(1, mystring, x)
If Position > 0 Then
ActiveCell.Characters(Position, p).Font.Color = RGB(255, 0, 0)
End If
End If
ActiveCell.Offset(1, 0).Activate
Loop
a = a + 1
Application.GoTo Sheet2.Cells(a, 1)
Loop
End Sub
Let me know if you have any other specific requirements so that the code can be altered. I hope this helps.

Macro Button to transfer info from certain cells in one spreadsheet into a different spreadsheet

I would like to be able to construct a macro that is easily able to transfer cell content from one spreadsheet to another. Let me elaborate in more detail: I currently have two spreadsheets open. See picture. The worksheet on the left works via a button macro that I made (not included in picture) and generates three different adjacent values. Thus every time I would click the button, a new output would be generated.
What I would like to be able to do is to transfer that information from the worksheet on the left to the worksheet on the right into columns G, H, and I respectively (by potentially clicking the button on the right worksheet) and then having it go to the next blank row to prepare for next round of generated values.
I'm having a bit of trouble constructing this (beginner). Could you offer some assistance?
Here is what I have so far:
Sub Button1_Click()
If Not Intersect(ActiveCell, Range("G:G")) Is Nothing Then
If ActiveCell.Offset(1, 0) <> vbNullString Then
ActiveCell.Offset(1, 0).Select
ActiveCell.Value = Workbooks("Model.xlsx").Worksheets("Optimization").Range("C100").Value
ActiveCell.Offset(0, 1).Value = Workbooks("Model.xlsx").Worksheets("Optimization").Range("D100").Value
ActiveCell.Offset(0, 2).Value = Workbooks("Model.xlsx").Worksheets("Optimization").Range("E100").Value
End If
End If
End Sub
Thanks!
This should work
Sub Button1_Click()
Const RowToTakeInformation = 100
Const ColumnToTakeInformation = 3
Const ColToWriteIn = 7
Dim WBDesired As Workbook: Set WBDesired = Workbooks("Model.xlsx")
Dim WSDesired As Worksheet: Set WSDesired = Worksheets("Optimization")
'If everything is in the same WB, I don't see a valid reason why to set it
Dim RowToInsert As Long
Dim CounterColumnsToWrite As Long
If WBDesired.Worksheets(WSDesired.Name).Cells(RowToTakeInformation, ColumnToTakeInformation).Value <> "" Then ' 1. If WBDesired.Worksheets(WSDesired.Name).Cells(RowToTakeInformation, ColumnToTakeInformation).Value <> ""
'here I'm assuming it's a table or something like it that automatically recalculates when something is inserted in between
RowToInsert = Cells(Rows.Count, ColToWriteIn).End(xlUp).Row - 1
Rows(RowToInsert).Insert Shift:=xlDown
For CounterColumnsToWrite = 0 To 2
Cells(RowToInsert, ColToWriteIn + CounterColumnsToWrite).Value = WBDesired.Worksheets(WSDesired.Name).Cells(RowToTakeInformation, ColumnToTakeInformation + CounterColumnsToWrite)
Next CounterColumnsToWrite
End If ' 1. If WBDesired.Worksheets(WSDesired.Name).Cells(RowToTakeInformation, ColumnToTakeInformation).Value <> ""
End Sub

Copy/pasting cells with shapes

How can copy a shape along with the cell it is in? When I copy manually the shape follows the cell, but when I do it with a macro I get everything else but the shape.
Cells(sourceRow, sourceColumn).Copy
Cells(targetRow, targedColumn).PasteSpecial
...
Range("A1").copy
Range("B2").PasteSpecial Operation:=xlPasteAll
I've tried all I could think of... but the shape just won't move.
Recorded the manual copy/paste and this is what I got:
Range("A1").Select
Selection.Copy
Range("A3").Select
ActiveSheet.Paste
I would do something like this to avoid having to actually select the cell:
Sub MoveShape()
Dim s As Shape
Dim T, L, celWidth, shpWidth, celHeight, shpHeight As Double
Dim rng As Range
Dim ws as Worksheet
Set s = ws.Shapes(1).Duplicate ''You'll have to get the index of the shape you want to copy
Set rng = Range("A3") ''Set this to your target range
T = rng.Top
L = rng.Left
celWidth = rng.Width
shpWidth = s.Width
celHeight = rng.Height
shpHeight = s.Height
s.Top = T + (celHeight - shpHeight) / 2
s.Left = L + (celWidth - shpWidth) / 2
End Sub
This will duplicate your shape, and put the resulting clone in the centre of your target range. You can change its position in the cell by modifying the s.Left and s.Top values.
You can now use Range("A3").Value = Range("A1").Value to copy the actual values of the cell to your target range
Try this
Range("A1").Select
Selection.Copy
Range("B1").Select
ActiveSheet.Paste

Increase speed of changing Excell cell's value with just a mouse [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I would like to increase the speed of changing Excel cell's value with a mouse only. I share my tool in hope that someone will like it and want to improve it.
This is an example. After clicking on a defined cell containing value, scrollbar appears on the right side of a cell. You can smoothly change its value with a mouse.
The tool is meant to change cells value and observe formulas values dynamically. You may simplify the code however some features should not be disabled. It should always stay dynamic, that is moving the srollbar should immediately influence other cells with formulas. The srollbar should not twinkle (changing colour grey and black).
You may simply download the scrollbar.xlsm file here and view the VBA code inside it.
Or you may put this code in your sheet where you want the scollbars to appear. The name of your sheet does not matter. Right click on the sheet's name and then click View Code. This is the place:
Insert there this code:
Option Explicit
Dim previousRow, c
Const scrlName As String = "scrlSh" ' the name of the scrollbar
Private Sub scrlSh_GotFocus()
ActiveSheet.Range(ActiveSheet.OLEObjects(scrlName).TopLeftCell.Offset(0, -1).Address).Activate
End Sub
Private Sub scrlSh_Scroll()
Dim rngCell As Range
Set rngCell = Sheets("Param").Range(ActiveSheet.OLEObjects(scrlName).LinkedCell)
ActiveSheet.OLEObjects(scrlName).TopLeftCell.Offset(0, -1).Value = _
rngCell.Offset(0, 1).Value + (ActiveSheet.OLEObjects(scrlName).Object.Value * rngCell.Offset(0, 3).Value)
Set rngCell = Nothing
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
' Macro concept by Przemyslaw Remin, VBA code written by Jaroslaw Smolinski
' The Sub Worksheet_SelectionChange and function SearchAdr have to be on each sheet where scrollbars are to appear
' Sheet Param is one for all sheets, only the columns A-G are used, othre columns can be used for something else
' Do not change the layout of A-G columns unless you want to modify the code
' Addresses in Param have to be with dollars (i.e. $A$3) or it may be named ranges of single cells
' (if it starts with $ it is a cell, otherwise it is a named range)
' the lower or upper case in addresses does not matter
Dim SheetFly As String, adr As String
Dim cCell As Range
Dim actSheet As Worksheet
Dim shScroll As Object
Set actSheet = ActiveSheet
' checks if scrollbar exists
If actSheet.Shapes.Count > 0 Then
For Each shScroll In actSheet.Shapes
If shScroll.Type = msoOLEControlObject And shScroll.Name = scrlName Then
Exit For ' scrollbar found, and the variable is set
End If
Next shScroll
End If
' if scrollbar does not exists then it is created
If shScroll Is Nothing Then
Set shScroll = ActiveSheet.OLEObjects.Add(ClassType:="Forms.ScrollBar.1", Link:=False, _
DisplayAsIcon:=False, Left:=0, Top:=0, Width:=64 * 3, Height:=15)
' scrollbar length is set as three adjesent columns
shScroll.Visible = False
shScroll.Name = scrlName
shScroll.Placement = xlMoveAndSize
End If
shScroll.Visible = False
adr = Target.AddressLocal
SheetFly = actSheet.Name
' here we set up in which cells the scrollbar has to appear. We set up only the number of rows
Set cCell = SearchAdr(SheetFly, adr, Sheets("Param").Range("B2:B40")) ' If needed it can be longer i.e. B2:B400
If Not cCell Is Nothing Then
With ActiveSheet.OLEObjects(scrlName)
.LinkedCell = "" ' temporary turn off of the link to the cell to avoid stange behaviour
.Object.Min = 0 ' the scale begins from 0, not negative
.Object.Max = Abs((cCell.Offset(0, 4).Value - cCell.Offset(0, 3).Value) / cCell.Offset(0, 5).Value)
.Object.SmallChange = 10 ' single change by one step
.Object.LargeChange = 10 ' change by jumps after clicking on scrollbar bar ("page up", "page down")
If Target.Value <> cCell.Offset(0, 2).Value And Target.Value >= cCell.Offset(0, 3).Value And Target.Value <= cCell.Offset(0, 4).Value Then
' setting up the cells value as close as possible to the value of input by hand
' rounded by step
' if value is out of defined range then the last value will be used
cCell.Offset(0, 2).Value = Abs((Target.Value - cCell.Offset(0, 3).Value) / cCell.Offset(0, 5).Value)
End If
'Protection in case the value is out of min and max range
If cCell.Offset(0, 2).Value > .Object.Max Then
cCell.Offset(0, 2).Value = .Object.Max
ElseIf cCell.Offset(0, 2).Value < .Object.Min Then
cCell.Offset(0, 2).Value = .Object.Min
End If
Target.Value = cCell.Offset(0, 3).Value + (cCell.Offset(0, 5).Value * cCell.Offset(0, 2).Value)
.Object.Value = cCell.Offset(0, 2).Value
.LinkedCell = "Param!" & cCell.Offset(0, 2).Address 'setting up linked cell
End With
' Setting up the position and width of scrollbar with reference to the cell
shScroll.Top = Target.Top
shScroll.Left = Target.Offset(0, 1).Left + 2 'position to the right + small margin
shScroll.Width = Target.Offset(0, 5).Left - Target.Offset(0, 1).Left - 2 'width of 5 columns
shScroll.Visible = True
End If
Set actSheet = Nothing
Set shScroll = Nothing
Set cCell = Nothing
End Sub
Private Function SearchAdr(SheetFly As String, SearchCell As String, rng As Range) As Range
Dim cCell As Range
Dim oOOo As Name
' Searching for the row with parameter for chosen cell
' The parameter have to be in one, continouse range
For Each cCell In rng
If cCell.Text = "" Then ' check if parameters have not finished
Set SearchAdr = Nothing
Exit Function ' stop if you find first empty cell for speeding
ElseIf Left(cCell.Text, 1) = "$" Then ' normal address
If cCell.Offset(0, 1).Text & "!" & UCase(cCell.Text) = SheetFly & "!" & UCase(SearchCell) Then
Set SearchAdr = cCell
Exit Function ' exit if find proper row with parameters
End If
Else ' means that found is a name
For Each oOOo In ActiveWorkbook.Names
If (oOOo.RefersTo = "=" & SheetFly & "!" & UCase(SearchCell)) And (UCase(oOOo.Name) = UCase(cCell.Text)) Then
Set SearchAdr = cCell
Exit Function ' exit if find proper row with parameters
End If
Next oOOo
End If
Next cCell
End Function
In your workbook you have to make sheet named Param where the parameters of scrollbar are stored. In column A and C put the name of your sheet where you want scrollbars to appear. The sheet looks like this:
Now you can enjoy the scrollbar after clicking the cell in the model sheet.
Note that you can define different min, max ranges and step of scrollbar change separately for every cell. Moreover, the min and max range can be negative.
I'd prefer:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Intersect(Target, Range("A1:A10")) Is Nothing Then Exit Sub
If OLEObjects.Count = 0 Then OLEObjects.Add "Forms.ScrollBar.1", , , , , , , Target.Offset(, 1).Left, Target.Top, 199, 15
With OLEObjects(1)
.Top = Target.Top
.object.max=200
Target = Application.Max(Target, .Object.Min)
Target = Application.Min(Target, .Object.Max)
.LinkedCell = Target.Address
End With
End Sub
To make the value change when clicking on left/right arrow or inside the scrollbar, I'd rather add:
Private Sub scrlSh_Change()
If ActiveSheet.OLEObjects(scrlName).LinkedCell <> "" Then
scrlSh_Scroll
End If
End Sub
I'd prefer use typed function like UCase$, Left$, ... rather than their variant equivalent (UCase, Left, ...), but for this macro the "true" performance is not really required.
Within your Worksheet_SelectionChange sub, I've replaced the actSheet, SheetFly and adr variables by their original values (as there are used only once). No real big improvment yet.