Very simple vba problem, not sure where it is going wrong, but:
Range("J21").Select
For tastetherainbow = 1 To 1000
skittle = ActiveCell.Offset(0, 2).Value
Selection.Interior.Color = skittle
ActiveCell.Offset(1, 0).Select
Next
The cell containing each appropriate skittle value contains an RGB code in the form RGB(r,g,b) , exactly as it should be for the VBA. I have tested it by copy pasting the cell's value into Selection.Interior.Color = paste without issue, but I get a "type mismatch" when it just uses skittle.
In fact, the only reason I am using skittle as a variable is that I had the same issue when I used Selection.Offset(0,2).Value to set the colour.
Rather lost! Could you let me know how to fix it, and why I have this issue.
Thanks!
It's recommended not using Select , Selection and ActiveCell , instead I preffer to start the For loop from Cell "J21" and just advance the row by 1.
Code
Option Explicit
Sub CellColors()
Dim Skittle As Long
Dim tastetherainbow As Long
' modify "Sheet1" to your sheet's name
With Sheets("Sheet1")
For tastetherainbow = 1 To 1000
Skittle = .Cells(tastetherainbow + 20, "L").Value
.Cells(tastetherainbow + 20, "J").Interior.Color = Skittle
Next tastetherainbow
End With
End Sub
Edited Code: converts the cell string format of "RGB(0,0,74)" to 0,0,74, then using the Split function putting the Strings into 3 elements of an array.
Then calculating Skittle Long numeric value using CInt and the RGB method.
Option Explicit
Sub CellColors()
Dim Skittle As Long
Dim CellRGBStr As String
Dim RGBInd() As String
Dim tastetherainbow As Long
With Sheets("Sheet3")
For tastetherainbow = 1 To 1000
If .Cells(tastetherainbow + 20, "L").Value <> "" Then
' use a string to store the "RGB(0,0,74)" as 0,0,74
CellRGBStr = Mid(.Cells(tastetherainbow + 20, "L").Value, 6, Len(.Cells(tastetherainbow + 20, "L").Value) - 7)
' split the CellRGBStr to 3 array elements
RGBInd = Split(CellRGBStr, ",")
' calculate the value of Skittle (using the RGB method)
Skittle = (CInt(RGBInd(0))) ^ 3 + (CInt(RGBInd(1))) ^ 2 + (CInt(RGBInd(2))) ^ 1
.Cells(tastetherainbow + 20, "J").Interior.Color = Skittle
End If
Next tastetherainbow
End With
End Sub
Another way to calculate Skittle is with the RGB function:
Skittle = RGB(CInt(RGBInd(0)), CInt(RGBInd(1)), CInt(RGBInd(2)))
Thanks for all the help guys, I modified it and cheated a little... This is running as part of a much larger macro, so I decided to just make the array of R, G, and B values explicit, and do it this way. From reading online Victor it says that RGB() expects values as integers - Long is more efficient but does the same thing nowadays no? Here is a working version. Couldn't have done it without you both thank you very much!
Sub ColourMeImpressed()
Dim Skittler As Long
Dim Skittleg As Long
Dim Skittleb As Long
Dim tastetherainbow As Long
With Sheets("Converter")
For tastetherainbow = 21 To 1000
Skittler = .Cells(tastetherainbow, "G")
Skittleg = .Cells(tastetherainbow, "H")
Skittleb = .Cells(tastetherainbow, "I")
Skittle = RGB(Skittler, Skittleg, Skittleb)
.Cells(tastetherainbow, "J").Interior.Color = Skittle
Next tastetherainbow
End With
End Sub
For those interested, here is a screenshot of the final result:
'little modification is required in your code as follows
Range("J21").Select
For tastetherainbow = 1 To 1000
skittle = ActiveCell.Offset(0, 2).Value
Selection.Interior.Color = RGB(skittle)
ActiveCell.Offset(1, 0).Select
Next
Related
It is really impossible to append more than 255 chars into a single cell by VBA macro in MS Excel?
Sample code:
Option Explicit
Sub TestSub()
Dim L As Long
' Const str = "1" & vbLf
Dim i As Integer
Range("A1").ClearContents
Range("A1").WrapText = True
For i = 1 To 260 ' any number greatest than 255
L = Range("A1").Characters.Count
Debug.Print L
Range("A1").Characters(L + 1, 1).Insert ("A")
Next i
End Sub
Added:
It is important to save previous formatting of chars in cell.
The following code will write 500 A into cell A1. Afterwards, every other A will be formatted bold.
Public Sub tmpSO()
For i = 1 To 500
Range("A1").Value = Range("A1").Value & "A"
Next i
For i = 1 To 500
If i Mod 2 = 0 Then Range("A1").Characters(i, 1).Font.Bold = True
Next i
End Sub
I hope that solves your problem.
Note: your code won't work because you are trying to insert a character after L + 1. Yet, your string is currently only L long and not L + 1. Once you have inserted another A you will have L + 1 characters in that cell. But not yet. So, if you are using your code with Range("A1").Characters(L, 1).Insert ("A") then it will work.
Edit#1:
The following code has been tested and correctly inserts 500 A into cell A1. Furthermore, some of the A will be formatted bold.
Sub TestSub()
Dim i As Integer
Range("A1").ClearContents
Range("A1").WrapText = True
Range("A1").Font.Bold = False
For i = 1 To 500
Range("A1").Characters(i, 1).Insert ("A")
Next i
For i = 1 To 500 Step 10
Range("A1").Characters(i, 3).Font.Bold = True
Next i
End Sub
question changed with this additional comment
https://stackoverflow.com/users/4742533/stayathome
will return and update this
initial answer
You can format the partial string using characters.
Code below appends your sample string to test string (300 characters long), then makes the last three italic, the three before that bold.
Sub LikeThis()
Dim StrIn As String
StrIn = "aaaabbbccc"
[a1] = Application.Rept("xyz", 100)
[a1].Value2 = [a1].Value2 & StrIn
[a1].Characters(Len([a1]) - 5, 3).Font.Bold = True
[a1].Characters(Len([a1]) - 2, 3).Font.Italic = True
End Sub
How can I set up a macro that will strip the letters from #####XX in column I and put them in to column L same row? Thanks!
Assuming you're working with the first sheet and you're always stripping off the last two characters while leaving the first 5 characters, the following code will work:
Public Sub StripOff()
Dim iRow as Integer
iRow = 2 'Assuming row 1 is headers, else make this 1
While Sheets(1).Range("I" + Cstr(iRow)).Value <> ""
Sheets(1).Range("L" + CStr(iRow)).Value = Right(Sheets(1).Range("I" + Cstr(iRow)).Value, 2)
Sheets(1).Range("I" + Cstr(iRow)).Value = Left(Sheets(1).Range("I" + Cstr(iRow)).Value, 5)
iRow = iRow + 1
Wend
End Sub
The operative words I'm understanding from your question are Cutting and strip. To my mind, this means that the last two letters are permanently removed from column I and placed in column L.
Sub cut2right()
Dim v As Long, vPFXS As Variant, vSFXS As Variant
With Worksheets("Sheet6")
vPFXS = .Range(.Cells(2, "I"), .Cells(Rows.Count, "I").End(xlUp))
ReDim vSFXS(1 To UBound(vPFXS), 1 To 1)
For v = LBound(vPFXS, 1) To UBound(vPFXS, 1)
If Len(vPFXS(v, 1)) > 1 Then
vSFXS(v, 1) = Right(vPFXS(v, 1), 2)
vPFXS(v, 1) = Left(vPFXS(v, 1), Len(vPFXS(v, 1)) - 2)
End If
Next v
.Cells(2, "I").Resize(UBound(vPFXS, 1), 1) = vPFXS
.Cells(2, "L").Resize(UBound(vPFXS, 1), 1) = vSFXS
End With
End Sub
Working with variant arrays should speed up working with many cells with variable length string values. If they were all the same length then manually running a Text-to-Columns command with a fixed length to an unused column and then copying and pasting the results to the appropriate column would have done just fine.
You can get the leading numeric characters from a string using the VBA Val function. To use this function on a worksheet you will need to create a User Defined Function (UDF) in a standard VBA module.
Function LeadingNumbers(Str As String) As Double
LeadingNumbers = Val(Str)
End Function
Simply enter the function in a cell and reference the cell containing the string you want "cleaned".
I am having trouble determining a way to enter a 1 or 0 into an adjacent cell to indicate whether or not a value is unique when working with a large dataset. I have read of multiple methods for accomplishing this, however none of them seem efficient for my purposes: I am using an instance of Excel 2010 (so I do not have the Distinct Count feature in PivotTables, and when I try to use PowerPivot it crashes my file due to processing limitations.
In this StackOverflow question: Simple Pivot Table to Count Unique Values there are suggestions to use SUMPRODUCT or COUNTIF, but when working with 50,000+ rows as I am, this causes terrible performance and a file size of ~35 MB instead of ~3 MB. I wanted to know if there is a better solution for a large, dynamic dataset whether it is a formula or VBA.
An example of what I would like to accomplish is (with the Unique column being the adjacent cell):
Name Week Unique
John 1 1
Sally 1 1
John 1 0
Sally 2 1
I attempted to script the same functionality of COUNTIF but with no success:
For Each Cell In ThisWorkbook.Worksheets("Overtime & Type Data").Range("Z2:Z" & DataLastRow)
If Worksheets("Overtime & Type Data").Cells(Cell.Row, 26) <> Worksheets("Overtime & Type Data").Cells(Cell.Row - 1, 26) Then
FirstCell = Cell.Row
End If
If (Worksheets("Overtime & Type Data").Range(Cells(FirstCell, 26), Cells(Cell.Row, 26)) = Worksheets("Overtime & Type Data").Range(Cells(Cell.Row, 26))) = True Then
Cell.Value = 1
Else
Cell.Value = 0
End If
Next Cell
This code ran on over 130,000 rows successfully in less than 3 seconds. Adjust the column letters to fit your dataset.
Sub tgr()
Const colName As String = "A"
Const colWeek As String = "B"
Const colOutput As String = "C"
Dim ws As Worksheet
Dim rngData As Range
Dim DataCell As Range
Dim rngFound As Range
Dim collUniques As Collection
Dim arrResults() As Long
Dim ResultIndex As Long
Dim UnqCount As Long
Set ws = ThisWorkbook.Sheets("Overtime & Type Data")
Set rngData = ws.Range(colName & 2, ws.Cells(Rows.Count, colName).End(xlUp))
Set collUniques = New Collection
ReDim arrResults(1 To rngData.Cells.Count, 1 To 1)
On Error Resume Next
For Each DataCell In rngData.Cells
ResultIndex = ResultIndex + 1
collUniques.Add ws.Cells(DataCell.Row, colName).Value & ws.Cells(DataCell.Row, colWeek).Value, ws.Cells(DataCell.Row, colName).Value & ws.Cells(DataCell.Row, colWeek).Value
If collUniques.Count > UnqCount Then
UnqCount = collUniques.Count
arrResults(ResultIndex, 1) = 1
Else
arrResults(ResultIndex, 1) = 0
End If
Next DataCell
On Error GoTo 0
ws.Cells(rngData.Row, colOutput).Resize(rngData.Cells.Count).Value = arrResults
End Sub
One approach is to sort by Name and Week. Then you can determine Unique for any row by comparing with the previous row.
If you need to preserve the order, you could first write a column of Index numbers (1, 2, 3, ...) to keep track of order. After calculating Unique, sort by Index to restore the original order.
The whole process could be done manually with relatively few steps, or automated with VBA.
I'm not sure how well this will work with 50000 values, but it goes through ~1500 in about a second.
Sub unique()
Dim myColl As New Collection
Dim isDup As Boolean
Dim myValue As String
Dim r As Long
On Error GoTo DuplicateValue
For r = 1 To Sheet1.UsedRange.Rows.Count
isDup = False
'Combine the value of the 2 cells together
' and add that string to our collection
'If it is already in the collection it errors
myValue = Sheet1.Cells(r, 1).Value & Sheet1.Cells(r, 2).Value
myColl.Add r, myValue
If isDup Then
Sheet1.Cells(r, 3).Value = "0"
Else
Sheet1.Cells(r, 3).Value = "1"
End If
Next
On Error GoTo 0
Exit Sub
DuplicateValue:
'The value is already in the collection so put a 0
isDup = True
Resume Next
End Sub
Just about any bulk operation will beat a loop involving worksheet cells. You might be able to trim the time down a bit by performing all of the calculations in memory and only returning the values back to the worksheet en masse when it is complete.
Sub is_a_dupe()
Dim v As Long, vTMP As Variant, vUNQs As Variant, dUNQs As Object
Debug.Print Timer
On Error GoTo bm_Uh_Oh
Set dUNQs = CreateObject("Scripting.Dictionary")
With Worksheets("Sheet1")
vTMP = .Range(.Cells(2, 1), .Cells(Rows.Count, 2).End(xlUp)).Value2
ReDim vUNQs(1 To UBound(vTMP, 1), 1 To 1)
For v = LBound(vTMP, 1) To UBound(vTMP, 1)
If dUNQs.Exists(Join(Array(vTMP(v, 1), vTMP(v, 2)))) Then
vUNQs(v, 1) = 0
Else
dUNQs.Add Key:=Join(Array(vTMP(v, 1), vTMP(v, 2))), _
Item:=vTMP(v, 2)
vUNQs(v, 1) = 1
End If
Next v
.Cells(2, 3).Resize(UBound(vUNQs, 1), 1) = vUNQs
End With
Debug.Print Timer
bm_Uh_Oh:
dUNQs.RemoveAll
Set dUNQs = Nothing
End Sub
Previous experience tells me that the variety of data (as well as hardware, etc) will impact timing the process but in my random sample data I received these elapsed times.
50K records ..... 0.53 seconds
130K records .... 1.32 seconds
500K records .... 4.92 seconds
I am a novice of Vba.
I have been litteraly fighting all day with this bit of code:
Sub ComandsCompactVisualization()
Dim x, i As Integer
Dim CellToAnalyse As Range
x = 2
i = 0
For i = 0 To 5 Step 1
Set CellToAnalyse = Worksheets("Comandi").Cells(x + i, 2)
If Not CellToAnalyse.Font.ColorIndex = 2 Then
Worksheets("Comandi").Rows("x+i:2").Hidden = True
End If
Next i
End Sub
I am trying to hide all the rows that in cell (x+i,2) have not got red text.
I am almost there but... Rows does not seem to accept as content Rows("x+i:2").
I obtain Runtime error 13 "Type mismatch".
If I substitute its content with Rows("2:2") row 2 is deleted but I am not any more able to hide all the other rows that do not have red text in column 2.
Ideas?
Anything between quotes "like this" is just a string. To perform arithmetic on x you need to do this first, then concatenate it to the other part of the string. Like this:
.Rows((x + i) & ":2")
BTW Isn't red 3..?
Sub ComandsCompactVisualization()
Dim x as long, i As Long 'You must declare ALL variables (x was as variant in your code)
Dim CellToAnalyse As Range
dim WS as Worksheet
'x = 2 'if x is always the same value, no need to calculate it each loop
'i = 0 'numbers are initialized to be 0, strings to be "", boolean to be false.
set WS=Sheets("Commandi")
For i = 0 To 5 ' Step 1
Set CellToAnalyse = WS.Cells(2 + i, 2)
If CellToAnalyse.Font.ColorIndex <> 2 Then
CellToAnalyse.entirerow.hidden=true
' WS.Rows(2+i).entirerow.hidden = true is the same result
End If
Next i
End Sub
I am having troubles with the coding above "9".
Sub ColourStates()
Dim intState As Integer
Dim strStateName As String
Dim intStateValue As Integer
Dim intColourLookup As Integer
Dim rngStates As Range
Dim rngColours As Range
Set rngStates = Range(ThisWorkbook.Names("STATES").RefersTo)
Set rngColours = Range(ThisWorkbook.Names("STATE_COLOURS").RefersTo)
With Worksheets("MainMap")
For intState = 1 To rngStates.Rows.Count
strStateName = rngStates.Cells(intState, 1).Text
intStateValue = rngStates.Cells(intState, 2).Value
' single colour
intColourLookup = Application.WorksheetFunction.Match(intStateValue, Range("STATE_COLOURS"), True)
With .Shapes(strStateName)
.Fill.Solid
.Fill.ForeColor.RGB = rngColours.Cells(intColourLookup, 1).Offset(0, 1).Interior.Color
End With
Next
End With
End Sub
Here is the link to the file itself: https://dl.dropboxusercontent.com/u/41007907/MapOfStates.xls
It works fine for values below 9, but I need it to work until 20.
Your array STATE_COLORS includes only values within 0 to 9 interval. Here are the steps you need to proceed with:
1) open excel file
2) go to Formulas Tag
3) click on the Name Manager
4) choose STATE_COLORS arrays
5) increase the values to 20
Get back to me if you have any other questions.