How to read a special character (arrow) from one cell in a macro and store it in another

JenniferMurphy

Well-known Member
Joined
Jul 23, 2011
Messages
2,676
Office Version
  1. 365
Platform
  1. Windows
I am trying to write a macro that will read in a column of special characters (up arrow, down arrow, etc.) that indicate whether a value is over or under some range. It will then scan another set of numbers, store the appropriate character in the cell to the left, and apply a color to both cells.

This code works as long as the characters are from the normal character set. But it fails if I select any special characters.

Here's the mini-sheet:

Book2
BCDEFGHIJ
1
2
3
4RatingsValuesExpectedUnrated
560Max8484
640Min3939
79191
8Too high77
9Goldilocks5555
10Too low4040
116161
126060
Sheet1


And here's the macro code. It is invoked by a Button control which is not included in the mini-sheet even though I selected a range that includes it.

VBA Code:
Sub RateEm()

Const rnCodes As String = "Codes"     'Column of code characters & colors
Const rnValues As String = "Values"   'Column of values to be rated
Const rnRatings As String = "Ratings" 'Column to put ratings
Dim Values() As Variant               'Values array
Dim NumValues As Long                 'Number of values

Dim Codes() As Variant    'Code characters
Dim NumCodes As Long      'Number of codes
Dim Colors() As Long      'Category colors

Dim Min As Long     'Minimum good value
Dim Max As Long     'Maximum good value
Dim iRtg As Long    'Rating index
Dim i As Long       'Loop index

Codes = Range(rnCodes).Value  'Read in the character codes & colors
NumCodes = UBound(Codes, 1)   'Number of codes
ReDim Colors(1 To NumCodes)   'Make colors array the same size
For i = 1 To NumCodes         'Get the code colors
  Colors(i) = Range(rnCodes).Cells(i, 1).Interior.Color
Next i

Min = Range("Min").Value        'Get the minimum value
Max = Range("Max").Value        'Get the maximum value
Values = Range(rnValues).Value  'Read in the character codes
NumValues = UBound(Values, 1)   'Get the number of values

For i = 1 To NumValues
  Select Case Range(rnValues).Cells(i, 1)
    Case Is > Max: iRtg = 1
    Case Is < Min: iRtg = 3
    Case Else: iRtg = 2
  End Select
  Range(rnValues).Cells(i, 1).Interior.Color = Colors(iRtg)
  Range(rnRatings).Cells(i, 1).Interior.Color = Colors(iRtg)
  Range(rnRatings).Cells(i, 1).Value = Codes(iRtg, 1)
Next i

End Sub

If I use characters from the normal text character set, it works.

1634174588202.png


But if I use special characters from another character set, I get this:

1634174734868.png


Is there a way I can use any character and make it work?

Thanks
 
More at beginner level so easier to understand like this :​
VBA Code:
Sub Demo1ez()
        Dim V, R&
        Application.ScreenUpdating = False
    With [F4].CurrentRegion
            V = Evaluate(Replace("(#<=C5)+(#<C6)", "#", .Columns(2).Address))
        For R = 2 To UBound(V)
            Cells(8 + V(R, 1), 3).Copy .Cells(R, 1)
        Next
    End With
        Application.ScreenUpdating = True
End Sub
I'll take a look at that when I get some time, but the lead you gave me gives me what I need to get this dang thing done.
 
Upvote 0

Excel Facts

Which lookup functions find a value equal or greater than the lookup value?
MATCH uses -1 to find larger value (lookup table must be sorted ZA). XLOOKUP uses 1 to find values greater and does not need to be sorted.
Take your time. Following my sample you can lighten your code …​
 
Upvote 0
More at beginner level so easier to understand like this :​

I have changed my objectives slightly. I need to add a code character as a prefix in addition to formatting the numerical ratings.

Here's the minisheet before the macro runs. Column G has the values to be rated. Column F is where the ratings are to go. Column H shows what I would like the ratings to look like. Column J contains the unrated values so I can restore them to their unrated state for testing. C5:C6 have the Max and Min values. And C8:C10 have the colors and the characters I would like to use in place of the "+", "-", & "=".

ZTest Color Macro.xlsm
BCDEFGHIJK
1
2
3
4RatingsValuesExpectedUnrated
560Max84+2484
640Min39-139
791+3191
8éToo high7-337
9èGoldilocks55=75% 55
10êToo low40=0% 40
1161+161
1260=100% 60
13
Sheet1
Cell Formulas
RangeFormula
H5:H12H5=IF(Values>Max,TEXT(Values-Max,"+0"),IF(Values<Min,TEXT(Min-Values,"-0"),(TEXT((Values-Min)/(Max-Min),"=0%"))))
Named Ranges
NameRefers ToCells
Max=Sheet1!$C$5H5:H12
Min=Sheet1!$C$6H5:H12
Values=Sheet1!$G$5:$G$12H5


And this is how it looks after the macro code runs:

1634197463904.png


And here's the code:

VBA Code:
Sub RateEm()

Const rnCodes As String = "Codes"     'Column of code characters & colors
Const rnValues As String = "Values"   'Column of values to be rated
Const rnRatings As String = "Ratings" 'Column to put ratings
Dim Values() As Variant               'Values array
Dim NumValues As Long                 'Number of values

Dim Codes() As Variant    'Code characters
Dim NumCodes As Long      'Number of codes

Dim Min As Long     'Minimum good value
Dim Max As Long     'Maximum good value
Dim i As Long       'Loop index

Codes = Range(rnCodes).Value  'Read in the character codes & colors
NumCodes = UBound(Codes, 1)   'Number of codes

Min = Range("Min").Value        'Get the minimum value
Max = Range("Max").Value        'Get the maximum value
Values = Range(rnValues).Value  'Read in the character codes
NumValues = UBound(Values, 1)   'Get the number of values
Dim iValue As Variant           'The numeric value
Dim sValue As String            'The formatted value
Dim iCode As Long               'The code index

For i = 1 To NumValues
  iValue = Range(rnValues).Cells(i, 1)
  Select Case iValue
    Case Is > Max: iCode = 1: sValue = "+" & Format(iValue - Max, "0")
    Case Is < Min: iCode = 3: sValue = "-" & Format(Min - iValue, "0")
    Case Else:     iCode = 2: sValue = "=" & Format((iValue - Min) / (Max - Min), "0%")
  End Select
  Range(rnRatings).Cells(i, 1).Value = sValue
  Range(rnRatings).Cells(i, 1).Interior.Color = _
        Range(rnCodes).Cells(iCode, 1).Interior.Color
  Range(rnValues).Cells(i, 1).Interior.Color = _
        Range(rnCodes).Cells(iCode, 1).Interior.Color
Next i

End Sub

Can you tell me how I can change the three sValue = statements so I can replace the "+", "-", & "=" with any characters in C8:C10? The three arrows in C8:C10 have, I believe, these hex values: x'00E9', x'00E8;, and '00EA'. I probably need to be able to specify the font, as well.

I don't have time to study your more efficient and compact code. I just need to get this blasted project out. So if you can just tell me how to modify those 3 statements, I would really appreciate it.

Thanks
 
Upvote 0
To work with your code I need your workbook link on a files host website like Dropbox 'cause too many errors, waste time …​
Anyway according to your previous post try this :​
VBA Code:
Sub Demo2()
        Dim V, W, R&
        Application.ScreenUpdating = False
    With Range("F5", [G4].End(xlDown)(1, 0)).Columns
           .Item(1).NumberFormat = "@"
            V = Evaluate(Replace("8+(#<=C5)+(#<C6)", "#", .Item(2).Address))
            W = Evaluate(Replace("IF(#>$C$5,#-$C$5,IF(#<$C$6,$C$6-#,(#-$C$6)/($C$5-$C$6)*100&""%""))", "#", .Item(2).Address))
        For R = 1 To UBound(V)
            With .Cells(R, 1)
                 .Interior.Color = Cells(V(R, 1), 3).Interior.Color
                 .Value2 = Cells(V(R, 1), 3).Text & W(R, 1)
            End With
        Next
    End With
        Application.ScreenUpdating = True
End Sub
 
Upvote 0
Maybe with this mod in your code :​
VBA Code:
For i = 1 To NumValues
        iValue = Range(rnValues)(i)
    Select Case iValue
           Case Is > Max:   iCode = 1:  sValue = iValue - Max
           Case Is < Min:   iCode = 3:  sValue = Min - iValue
           Case Else:       iCode = 2:  sValue = Format((iValue - Min) / (Max - Min), "0%")
    End Select
    With Range(rnRatings)(i)
        .Interior.Color = Range(rnCodes)(iCode).Interior.Color
         Range(rnValues)(i).Interior.Color = .Interior.Color
        .Value2 = Range(rnCodes)(iCode).Text & sValue
    End With
Next
 
Upvote 0
As I have amended several times the previous post so take care if you get the ultimate one …​
 
Upvote 0
Demo2 revamped for a little optimization :​
VBA Code:
Sub Demo2r()
        Dim V, W, R&
        Application.ScreenUpdating = False
    With Range("F5", [G4].End(xlDown)(1, 0)).Columns
           .Item(1).NumberFormat = "@"
            V = Evaluate(Replace("8+(#<=C5)+(#<C6)", "#", .Item(2).Address))
            W = Evaluate(Replace("IF(#>$C$5,#-$C$5,IF(#<$C$6,$C$6-#,(#-$C$6)/($C$5-$C$6)*100&""%""))", "#", .Item(2).Address))
        For R = 1 To UBound(V)
           .Cells(R, 1).Interior.Color = Cells(V(R, 1), 3).Interior.Color
            V(R, 1) = Cells(V(R, 1), 3).Text & W(R, 1)
        Next
           .Value2 = V
    End With
        Application.ScreenUpdating = True
End Sub
 
Upvote 0
Removing the useless to lighten your procedure this is its revamped version :​
VBA Code:
Sub RateEmR2D2()
    Dim M&, N&, R&, C%, S$
        M = [Max].Value2
        N = [Min].Value2
        Application.ScreenUpdating = False
    With [Ratings]
           .NumberFormat = "@"
        For R = 1 To .Rows.Count
            With .Cells(R, 2)
                Select Case .Value2
                       Case Is > M:     C = 1:  S = .Value2 - M
                       Case Is < N:     C = 3:  S = N - .Value2
                       Case Else:       C = 2:  S = Format$((.Value2 - N) / (M - N), "0%")
                End Select
            End With
               .Cells(R).Resize(, 2).Interior.Color = Range("Codes")(C).Interior.Color
               .Cells(R).Value2 = Range("Codes")(C).Text & S
        Next
    End With
        Application.ScreenUpdating = True
End Sub

As a reminder : Dim M& is equal to Dim M as Long … % = Integer … $ = String …​
 
Last edited:
Upvote 0
Removing the useless to lighten your procedure this is its revamped version :​
VBA Code:
Sub RateEmR2D2()
    Dim M&, N&, R&, C%, S$
        M = [Max].Value2
        N = [Min].Value2
        Application.ScreenUpdating = False
    With [Ratings]
           .NumberFormat = "@"
        For R = 1 To .Rows.Count
            With .Cells(R, 2)
                Select Case .Value2
                       Case Is > M:     C = 1:  S = .Value2 - M
                       Case Is < N:     C = 3:  S = N - .Value2
                       Case Else:       C = 2:  S = Format$((.Value2 - N) / (M - N), "0%")
                End Select
            End With
               .Cells(R).Resize(, 2).Interior.Color = Range("Codes")(C).Interior.Color
               .Cells(R).Value2 = Range("Codes")(C).Text & S
        Next
    End With
        Application.ScreenUpdating = True
End Sub

As a reminder : Dim M& is equal to Dim M as Long … % = Integer … $ = String …​
Thanks. This is very helpful. I'm working on it....:unsure:o_O?
 
Upvote 0

Forum statistics

Threads
1,223,362
Messages
6,171,639
Members
452,412
Latest member
MitchAgain

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top