"Bad name or number" when trying to run VBA - excel

I am using an excel file that has some code that will compile data into a .txt file when a button is clicked. I am getting an error "Bad name or number" when the code is run. Here is a screenshot where I am getting the error. THis is my first time using this so I don't really know what the issue is. Thank you!
enter image description here
This code should create a .txt file that I can use to create a map on mapchart.net
Here is the full code:
Sub export_Click()
Set fs = CreateObject("Scripting.FileSystemObject")
Dim pathname As String
Dim iRet As Integer
Dim strMsg As String
Dim dict As Object, key, val
Set dict = CreateObject("Scripting.Dictionary")
Dim wsName As String
wsName = Replace(ActiveSheet.Name, " ", "_")
Dim rgch As String
Dim RandomString As String
rgch = "abcdefghijklmnopqrstuvwxyz"
rgch = rgch & UCase(rgch) & "0123456789"
Dim i As Long
For i = 1 To 8
RandomString = RandomString & Mid$(rgch, Int(Rnd() * Len(rgch) + 1), 1)
Next
pathname = ActiveWorkbook.Path & "\mapchartSave_" & wsName & "_" & RandomString & ".txt"
Debug.Print (findTotalRows())
Set a = fs.CreateTextFile(pathname, True)
Dim outp As String
Dim totalRows As String
Dim final As String
Dim cell As Range
Dim color As String
Dim countyName As String
outp = "{'groups':{'"
totalRows = findTotalRows()
'--> Loop through each cell in column E (COLOR)
For Each cell In ActiveSheet.Range("D2:D" & totalRows)
color = LCase(rgb2hex(cell))
If Not color = "#d1dbdd" Then
countyName = "'" & cell.Offset(0, -3).Value & "',"
If Not dict.Exists(color) Then
dict.Add color, countyName
Else
dict(color) = dict(color) & countyName
End If
End If
Next cell
Dim boxNo As Integer
boxNo = 0
For Each key In dict.Keys
outp = outp & key & "':{'div':'#box" & boxNo & "','label':'Label Text " & boxNo & "','paths':[" & dict(key)
outp = Left(outp, Len(outp) - 1)
outp = outp & "]},'"
boxNo = boxNo + 1
'--> Debug.Print key, dict(key)
Next key
'--> Remove the trailing comma from the output
outp = Left(outp, Len(outp) - 2)
outp = outp & "},'title':'Legend Title','borders':'#000000'}"
'--> Replace all ' with ""
final = Replace(outp, "'", """")
a.WriteLine (final)
a.Close
strMsg = "Your MapChart configuration file was saved as mapchartSave_" & wsName & "_" & RandomString & ".txt "
iRet = MsgBox(strMsg, vbOKOnly, "Success")
End Sub
Function rgb2hex(rcell) As String
Dim cellColor As String
'--> Check if cell has color from conditional formatting
Dim cfColor As String
cfColor = Cells(rcell.Row, rcell.Column).DisplayFormat.Interior.color
If cfColor = "65535" Then
cellColor = Hex(rcell.Interior.color)
Else
cellColor = Hex(cfColor)
End If
cellColor = Right("000000" & cellColor, 6)
rgb2hex = "#" & Right(cellColor, 2) & Mid(cellColor, 3, 2) & Left(cellColor, 2)
End Function
Function findTotalRows() As String
Dim N As Long
N = Cells(1, 1).End(xlDown).Row
findTotalRows = CStr(N)
End Function
Sub reset_Click()
Dim cell As Range
Dim color As String
Dim totalRows As String
totalRows = findTotalRows()
For Each cell In ActiveSheet.Range("D2:D" & totalRows)
color = LCase(rgb2hex(cell))
If Not color = "#d1dbdd" Then
cell.Interior.color = RGB(209, 219, 221)
End If
Next cell
End Sub

Related

How can you extract characters from a cell, that have a specific property (like underlined)? [duplicate]

I have an Excel cell with text. Some words are bolded. Those words are keywords and should be extracted to another cell in the row for identification of the keywords.
Example:
Text in Cell:
I want to use Google Maps for route informations
Output:
Google; Maps; route;
You can also use this UDF to produce same result. Please enter below code in module.
Public Function findAllBold(ByVal rngText As Range) As String
Dim theCell As Range
Set theCell = rngText.Cells(1, 1)
For i = 1 To Len(theCell.Value)
If theCell.Characters(i, 1).Font.Bold = True Then
If theCell.Characters(i + 1, 1).Text = " " Then
theChar = theCell.Characters(i, 1).Text & ", "
Else
theChar = theCell.Characters(i, 1).Text
End If
Results = Results & theChar
End If
Next i
findAllBold = Results
End Function
Now you can use newly created function to return bold values from any cell.
Try this
Option Explicit
Sub Demo()
Dim ws As Worksheet
Dim str As String, strBold As String
Dim isBold As Boolean
Dim cel As Range
Dim lastRow As Long, i As Long
Set ws = ThisWorkbook.Sheets("Sheet1") 'change Sheet1 to your data sheet
isBold = False
With ws
lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row 'last row with data in Column A
For Each cel In .Range("A1:A" & lastRow).Cells 'loop through each cell in Column A
strBold = ""
For i = 1 To Len(cel.Value)
If cel.Characters(Start:=i, Length:=1).Font.Bold = True Then 'check if character is bold
isBold = True
str = Mid(cel.Value, i, 1)
If cel.Characters(Start:=i, Length:=1).Text = " " Then 'check for space
strBold = strBold & "; "
isBold = False
Else
strBold = strBold & str
End If
Else
If isBold Then
strBold = strBold & "; "
isBold = False
End If
End If
Next
cel.Offset(0, 1) = strBold
Next
End With
End Sub
Derived this code from here.

Excel VBA script to output TSV is giving leading and trailing double quotes, how can I remove them

Sub ExportDataTSV()
Dim BCS As Worksheet
Dim Ctrl As Worksheet
Dim ws As Worksheet
Dim FName As String
Dim insertValues As String
Application.EnableEvents = False
Application.ScreenUpdating = False
Set BCS = ThisWorkbook.Sheets(Sheet2.Name)
Set Ctrl = ThisWorkbook.Sheets(Sheet1.Name)
fileDate = Year(Now) & "_" & Month(Now) & "_" & Day(Now) & "_" & Format(Now, "hh")
#If Mac Then
NameFolder = "documents folder"
If Int(Val(Application.Version)) > 14 Then
'You run Mac Excel 2016
folder = _
MacScript("return POSIX path of (path to " & NameFolder & ") as string")
'Replace line needed for the special folders Home and documents
folder = _
Replace(SpecialFolder, "/Library/Containers/com.microsoft.Excel/Data", "")
Else
'You run Mac Excel 2011
folder = MacScript("return (path to " & NameFolder & ") as string")
End If
FName = folder & ":bcs_output.txt"
#Else
folder = Environ$("userprofile")
FName = folder & "\Documents\bcs_output_" & fileDate & ".txt"
#End If
If Ctrl.Range("D9") = "" Or Ctrl.Range("D10") = "" Then
MsgBox "Please enter the Scenario Year and Scenario you wish to save and click again", vbOKOnly
Exit Sub
End If
Ctrl.Range("D9").Copy
BCS.Range("AS2").PasteSpecial Paste:=xlPasteValues
Ctrl.Range("D10").Copy
BCS.Range("AT2").PasteSpecial Paste:=xlPasteValues
Call ClearFile(FName)
With BCS
.AutoFilter.ShowAllData
numrows = .Cells(.Rows.Count, 1).End(xlUp).Row
numcol = .Cells(2, Columns.Count).End(xlToLeft).Column
.Range("AS1").Value = "scenario_year"
.Range("AS2:AS" & numrows).FillDown
.Range("AT1").Value = "scenario"
.Range("AT2:AT" & numrows).FillDown
.Range("AU1").Value = "save_date"
.Range("AU2").Formula = "=NOW()"
.Range("AU2:AU" & numrows).FillDown
.Range("AU2:AU" & numrows).NumberFormat = "yyyy-mm-dd hh:mm"
For x = 2 To numrows
Set rng1 = .Range("A" & x & ":R" & x)
Set rng2 = .Range("AC" & x & ":AF" & x)
Set rng3 = .Range("AH" & x & ":AK" & x)
Set rng4 = .Range("AN" & x & ":AO" & x)
Set rng5 = .Range("AS" & x & ":AU" & x)
Set Data = Union(rng1, rng2, rng3, rng4, rng5)
insertValues = Join2D(ToArray(Data), Chr(9))
Call ConvertText(FName, insertValues)
Next x
End With
With BCS
.Activate
.Range("A1").Select
End With
Ctrl.Activate
Application.ScreenUpdating = True
MsgBox "Cluster Data saved to " & FName & ", please upload the file here: https://awsfinbi.corp.amazon.com/s/dcgs_abv/submit", vbOKOnly
Application.EnableEvents = True
End Sub
Function ToArray(rng) As Variant()
Dim arr() As Variant, r As Long, nr As Long
Dim ar As Range, c As Range, cnum As Long, rnum As Long
Dim col As Range
nr = rng.Areas(1).Rows.Count
ReDim arr(1 To nr, 1 To rng.Cells.Count / nr)
cnum = 0
For Each ar In rng.Areas
For Each col In ar.Columns
cnum = cnum + 1
rnum = 1
For Each c In col.Cells
arr(rnum, cnum) = c.Value
rnum = rnum + 1
Next c
Next col
Next ar
ToArray = arr
End Function
Public Function Join2D(ByVal vArray As Variant, Optional ByVal sWordDelim As String = " ", Optional ByVal sLineDelim As String = vbNewLine) As String
Dim i As Long, j As Long
Dim aReturn() As String
Dim aLine() As String
ReDim aReturn(LBound(vArray, 1) To UBound(vArray, 1))
ReDim aLine(LBound(vArray, 2) To UBound(vArray, 2))
For i = LBound(vArray, 1) To UBound(vArray, 1)
For j = LBound(vArray, 2) To UBound(vArray, 2)
'Put the current line into a 1d array
aLine(j) = vArray(i, j)
Next j
'Join the current line into a 1d array
aReturn(i) = Join(aLine, sWordDelim)
Next i
Join2D = Join(aReturn, sLineDelim)
End Function
Public Function ClearFile(myfile)
Open myfile For Output As #1: Close #1
End Function
Public Function ConvertText(myfile As String, strTxt As String)
Open myfile For Append As #1
Write #1, strTxt
Close #1
End Function
The above functions are what I have strung together from various SO post and googles. It works to a large degree, but when it creates the txt file with the tab delimiter it gives an output where in the text separator is a single quote. However, the entire line is wrapped in double quotes. So the output looks something like "'Field1'\t'Field2'\t'Field3'" . That is not a valid TSV format for loading into a database like Redshift due to the double quotes. I need the double quotes to not be in the file, can anyone identify why it is adding them? Is there a way to prevent it or a better way to create a tab delimited file output for loading to Redshift?
For further information it MUST be a txt with tab delimiter, I have no control over that requirement.
https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/writestatement
Unlike the Print # statement, the Write # statement inserts commas
between items and quotation marks around strings as they are written
to the file. You don't have to put explicit delimiters in the list.
Write # inserts a newline character, that is, a carriage
return-linefeed (Chr(13) + Chr(10) ), after it has written the final
character in outputlist to the file.
To not add quotes switch to Print:
Print #1, strTxt

Save Array as Tab Delimited Text file in VBA

Sub ExportDataTSV()
Dim BCS As Worksheet
Dim Ctrl As Worksheet
Dim ws As Worksheet
Dim FName As String
Dim insertValues As String
Application.ScreenUpdating = False
Set BCS = ThisWorkbook.Sheets(Sheet2.Name)
Set Ctrl = ThisWorkbook.Sheets(Sheet1.Name)
#If Mac Then
NameFolder = "documents folder"
If Int(Val(Application.Version)) > 14 Then
'You run Mac Excel 2016
folder = _
MacScript("return POSIX path of (path to " & NameFolder & ") as string")
'Replace line needed for the special folders Home and documents
folder = _
Replace(SpecialFolder, "/Library/Containers/com.microsoft.Excel/Data", "")
Else
'You run Mac Excel 2011
folder = MacScript("return (path to " & NameFolder & ") as string")
End If
FName = folder & "bcs_output.tsv"
#Else
folder = Environ$("userprofile")
Debug.Print folder
FName = folder & "Documents\bcs_output.tsv"
#End If
If Ctrl.Range("D9") = "" Or Ctrl.Range("D10") = "" Then
MsgBox "Please enter the Scenario Year and Scenario you wish to save and click again", vbOKOnly
Exit Sub
End If
Ctrl.Range("D9").Copy
BCS.Range("AS2").PasteSpecial Paste:=xlPasteValues
Ctrl.Range("D10").Copy
BCS.Range("AT2").PasteSpecial Paste:=xlPasteValues
With BCS
numrows = .Cells(.Rows.Count, 1).End(xlUp).Row
numcol = .Cells(2, Columns.Count).End(xlToLeft).Column
.Range("AS1").Value = "scenario_year"
.Range("AS2:AS" & numrows).FillDown
.Range("AT1").Value = "scenario"
.Range("AT2:AT" & numrows).FillDown
.Range("AU1").Value = "save_date"
.Range("AU2").Formula = "=NOW()"
.Range("AU2:AU" & numrows).FillDown
.Range("AU2:AU" & numrows).NumberFormat = "yyyy-mm-dd hh:mm"
For x = 2 To numrows
Set rng1 = .Range("A" & x & ":R" & x)
Set rng2 = .Range("AC" & x & ":AF" & x)
Set rng3 = .Range("AH" & x & ":AK" & x)
Set rng4 = .Range("AN" & x & ":AO" & x)
Set rng5 = .Range("AS" & x & ":AU" & x)
Set Data = Union(rng1, rng2, rng3, rng4, rng5)
insertValues = Join2D(ToArray(Data), Chr(9))
Debug.Print insertValues
Call ConvertText(FName, insertValues)
Next x
End With
With BCS
.Activate
.Range("A1").Select
End With
Ctrl.Activate
Application.ScreenUpdating = True
MsgBox "Cluster Data saved to your documents folder, please upload the file here: ", vbOKOnly
End Sub
Function ToArray(rng) As Variant()
Dim arr() As Variant, r As Long, nr As Long
Dim ar As Range, c As Range, cnum As Long, rnum As Long
Dim col As Range
nr = rng.Areas(1).Rows.Count
ReDim arr(1 To nr, 1 To rng.Cells.Count / nr)
cnum = 0
For Each ar In rng.Areas
For Each col In ar.Columns
cnum = cnum + 1
rnum = 1
For Each c In col.Cells
arr(rnum, cnum) = c.Value
rnum = rnum + 1
Next c
Next col
Next ar
ToArray = arr
End Function
Public Function Join2D(ByVal vArray As Variant, Optional ByVal sWordDelim As String = " ", Optional ByVal sLineDelim As String = vbNewLine) As String
Dim i As Long, j As Long
Dim aReturn() As String
Dim aLine() As String
ReDim aReturn(LBound(vArray, 1) To UBound(vArray, 1))
ReDim aLine(LBound(vArray, 2) To UBound(vArray, 2))
For i = LBound(vArray, 1) To UBound(vArray, 1)
For j = LBound(vArray, 2) To UBound(vArray, 2)
'Put the current line into a 1d array
aLine(j) = vArray(i, j)
Next j
'Join the current line into a 1d array
aReturn(i) = Join(aLine, sWordDelim)
Next i
Join2D = Join(aReturn, sLineDelim)
End Function
Function ConvertText(myfile As String, strTxt As String)
Dim objStream
Set objStream = CreateObject("ADODB.Stream")
With objStream
'.Charset = "utf-8"
.Open
.WriteText strTxt
.SaveToFile myfile, 2
'.Close
End With
'Set objStream = Nothing
End Function
I attempted the above to write the non-contiguous ranges to a tab delimited file. I get a 3004 error - Unable to write file from that code. I am not sure why it can't write the file and since I can't even write the file I can't tell if it will write each row of data until there are no more. Can anyone assist with at least helping me get the file to write?
You need to separate folder and "Documents\bcs_output.tsv" with a backslash. In MacOS I believe the path separator is ":" (colon), not "\" (backslash).

Comparing large strings with percentage differnce in excel

Is there a way to compare a large string of text with another large string of text in another cell and get percentage string match ignoring case sensativity.
For example:
Cell a1: Please support this application inquiry
Cell b2: Please support another application process
do comparison of both cells and return percentage match: %60 match with possibility of highlighting.
Thanks
I tried column match.
Function CompareString(rngS1 As Range, rngS2 As Range, strType As String, Optional boolCase As Boolean = True) As Variant
Dim vW1, vW2
Dim oDic As Object
Dim lngW As Long, lngU As Long, lngM As Long, lngTemp As Long, rngCell As Range
Dim strTemp As String, strC As String, strB As String
vW2 = Split(Application.WorksheetFunction.Trim(Replace(Replace(rngS2.Text, ".", ""), Chr(100), " ")), " ")
Set oDic = CreateObject("Scripting.Dictionary")
For lngW = LBound(vW2) To UBound(vW2) Step 1
strTemp = vW2(lngW)
With oDic
If Not .exists(strTemp) Then
lngU = lngU + 1
.Add strTemp, lngU
End If
End With
Next lngW
Set oDic = Nothing
For Each rngCell In rngS1.Cells
strC = Application.WorksheetFunction.Trim(Replace(Replace(rngCell.Text, ".", ""), Chr(100), " "))
If strC <> "" Then
If strC = rngS2.Text Then
lngM = lngU
strB = rngS2.Text
Else
vW1 = Split(strC, " ")
lngTemp = 0
For lngW = LBound(vW2) To UBound(vW2) Step 1
strTemp = vW2(lngW)
If boolCase Then
lngTemp = lngTemp + rngS1.Parent.Evaluate("SUMPRODUCT(--ISNUMBER(FIND("" " & strTemp & " "","" " & strC & " "")))")
Else
lngTemp = lngTemp - IsNumeric(Application.Match(strTemp, vW1, 0))
End If
Next lngW
If lngTemp > lngM Then
lngM = lngTemp
strB = rngCell.Text
End If
End If
End If
Next rngCell
Select Case UCase(strType)
Case "P"
CompareString = lngM / lngU
Case "S"
CompareString = strB
End Select
End Function
This is pretty simple but should give you what you're looking for. It splits the strings in the cells up based on spaces and should return the overlap of words within them as a percent.
Sub test()
MsgBox 100 * CompareTwoStrings(Range("A1").Value2, Range("B2").Value2)
End Sub
Function CompareTwoStrings(ByVal str1 As String, ByVal str2 As String) As Double
str1 = ReplaceSpecialChars(str1)
str2 = ReplaceSpecialChars(str2)
Dim splitStrShorter As Variant
Dim splitStrLonger As Variant
If (Len(str1) - Len(Replace(str1, " ", ""))) > (Len(str2) - Len(Replace(str2, " ", ""))) Then
splitStrLonger = Split(LCase(str1), " ")
splitStrShorter = Split(LCase(str2), " ")
Else
splitStrLonger = Split(LCase(str2), " ")
splitStrShorter = Split(LCase(str1), " ")
End If
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
Dim i As Long
For i = 0 To UBound(splitStrLonger)
If Not dict.exists(splitStrLonger(i)) Then
dict.Add splitStrLonger(i), ""
End If
Next i
Dim frequency As Long
For i = 0 To UBound(splitStrShorter)
If dict.exists(splitStrShorter(i)) Then
frequency = frequency + 1
End If
Next i
CompareTwoStrings = frequency / (UBound(splitStrLonger) + 1)
End Function
Function ReplaceSpecialChars(ByVal strToReplace As String) As String
Dim specialChars As String
specialChars = "`,-,=,!,#,#,$,%,^,&,*,(,),_,+,[,],\,{,},|,;,',:," & Chr(34) & ",.,/,<,>,?"
Dim char As Variant
For Each char In Split(specialChars, ",")
strToReplace = Replace(strToReplace, char, "")
Next
ReplaceSpecialChars = strToReplace
End Function

Extract bold words in string

I have an Excel cell with text. Some words are bolded. Those words are keywords and should be extracted to another cell in the row for identification of the keywords.
Example:
Text in Cell:
I want to use Google Maps for route informations
Output:
Google; Maps; route;
You can also use this UDF to produce same result. Please enter below code in module.
Public Function findAllBold(ByVal rngText As Range) As String
Dim theCell As Range
Set theCell = rngText.Cells(1, 1)
For i = 1 To Len(theCell.Value)
If theCell.Characters(i, 1).Font.Bold = True Then
If theCell.Characters(i + 1, 1).Text = " " Then
theChar = theCell.Characters(i, 1).Text & ", "
Else
theChar = theCell.Characters(i, 1).Text
End If
Results = Results & theChar
End If
Next i
findAllBold = Results
End Function
Now you can use newly created function to return bold values from any cell.
Try this
Option Explicit
Sub Demo()
Dim ws As Worksheet
Dim str As String, strBold As String
Dim isBold As Boolean
Dim cel As Range
Dim lastRow As Long, i As Long
Set ws = ThisWorkbook.Sheets("Sheet1") 'change Sheet1 to your data sheet
isBold = False
With ws
lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row 'last row with data in Column A
For Each cel In .Range("A1:A" & lastRow).Cells 'loop through each cell in Column A
strBold = ""
For i = 1 To Len(cel.Value)
If cel.Characters(Start:=i, Length:=1).Font.Bold = True Then 'check if character is bold
isBold = True
str = Mid(cel.Value, i, 1)
If cel.Characters(Start:=i, Length:=1).Text = " " Then 'check for space
strBold = strBold & "; "
isBold = False
Else
strBold = strBold & str
End If
Else
If isBold Then
strBold = strBold & "; "
isBold = False
End If
End If
Next
cel.Offset(0, 1) = strBold
Next
End With
End Sub
Derived this code from here.

Resources