Converting bullets Text to HTML using VBA function Excel - excel

I have lots of products which have description including bullets, which I want to convert it to html form excel file.
Description of product be like in one cell :
• Our aim is to be devoted to building a sustainable future.
• We are keen to preserve the human being and its environment.
• It is best for all skin types
some macro code I have tried is like:
Sub aTest()
Dim rCell As Range, spl As Variant, i As Long
For Each rCell In Selection
spl = Split(rCell, Chr(10))
For i = LBound(spl) To UBound(spl)
spl(i) = Chr(60) & "li" & Chr(62) & spl(i) & Chr(60) & "/li" & Chr(62)
Next i
rCell = Join(spl, Chr(10))
Next rCell
Selection.ColumnWidth = 200
Selection.EntireRow.AutoFit
Selection.EntireColumn.AutoFit
End Sub
this code gives me output including bullets within it:
Expected:
<li> Our aim is to be devoted to building a sustainable future. </li>
<li> We are keen to preserve the human being and its environment.</li>
<li> It is best for all skin types</li>
Could anyone please help me get this correct, as I do not have any idea of VB.
Moreover, it would be great to have Function rather than macro.
Thanks
Update: I have this whole content within one cell and want it to convert to html together. Is that possible?
BIODERMA is a brand of NAOS, the world’s number 1 cosmetic company. BIODERMA has been dedicated to skin health for 40 years and has pioneered many breakthroughs in dermatological care. We are a company that provides high-quality skin care products developed by medical professionals with the absolute highest safety standards.
Key Features:
• Our aim is to be devoted to building a sustainable future.
• We are keen to preserve the human being and its environment.
• It is best for all skin types

Private Function ConvertBulletToHTML(argInput As String) As String
Dim cleanArr() As String
cleanArr = Split(argInput, vbLf)
Dim i As Long
For i = 0 To UBound(cleanArr)
If Instr(cleanArr(i), Chr(149)) <> 0 Then
cleanArr(i) = Replace(cleanArr(i), Chr(149), vbNullString)
cleanArr(i) = "<li>" & Trim(cleanArr(i)) & "</li>"
End If
Next i
ConvertBulletToHTML = "<div>" & Join(cleanArr, vbLf) & "</div>"
End Function
This is the output:
<div><li>Our aim is to be devoted to building a sustainable future.</li>
<li>We are keen to preserve the human being and its environment.</li>
<li>It is best for all skin types</li></div>
And output for the updated question:
<div>BIODERMA is a brand of NAOS, the world’s number 1 cosmetic company. BIODERMA has been dedicated to skin health for 40 years and has pioneered many breakthroughs in dermatological care. We are a company that provides high-quality skin care products developed by medical professionals with the absolute highest safety standards.
Key Features:
<li>Our aim is to be devoted to building a sustainable future.</li>
<li>We are keen to preserve the human being and its environment.</li>
<li>It is best for all skin types</li></div>
Remove the Trim in the for loop if you do not want it trimmed.
Note: vbLf is the same as Chr(10) so you can just use the built-in constant.

Try:
spli(i) = Replace(spli(i), Chr(149), "")
You must check if it is actually Chr(149) and change it to something else if it is not.
Other way - assuming it is the first character in your spli(i)
spli(i) = Right(spli(i), Len(spli(i)) - 1)
This must be applied before adding html tags.

Related

Count Exact Match using Excel VBA

I am trying to find the exact matching word using Excel VBA, but failed to do so as either due to case sensitivity or partial match.
Here is my data
Experience Column contains certain keywords and I am extracting those keywords based on master list
The problems in Result are
It is showing UI2 means, UI 2 times, but as we can see in experience it is only 1 time
Same with GO, it shows 2 : One from Go and other from Google
NoSQL has been extracted into NoSQL and SQL, however there were two different skill set: NoSQL and SQL and since the experience doesn't have SQL, it shouldn't be extracted
There is a skill set called "R" in master file, it was difficult to extract particular R as it accounts for every R
Here is my code snip
I have read so many articles, but didn't find appropriate solution. Kindly help.
Thanks
You need to account for word boundaries if you don't want "Go" to (eg) match "Google". You might be better off using a regex approach to find matches.
Note: to avoid matching "Go" with "go" you need the match to be case-sensitive, but to avoid misses on other terms you might need to pass all possible case variants like (eg) "mySQL|MySQL".
Sub matchTester()
Dim s As String, skill
s = "I go to school now and have used R, MySQL, noSQL and " & _
"SQL and Go in my Ratings job at Google. I like R"
For Each skill In Array("SQL", "noSQL|NoSQL", "mySQL|MySQL", "R", "Go", "VBA", "C#")
Debug.Print skill, CountMatches(s, skill)
Next skill
End Sub
Function CountMatches(sIn As String, countThis) As Long
Dim regEx As Object, matches As Object
With CreateObject("vbscript.regexp")
.Global = True
.IgnoreCase = False
.Pattern = "\b(" & countThis & ")\b" 'add word boundaries
Set matches = .Execute(sIn)
End With
CountMatches = matches.Count
End Function
output:
SQL 1
noSQL|NoSQL 1
mySQL|MySQL 1
R 2
Go 1
VBA 0
C# 0

Extract XBRL facts to Excel

I would like to cycle through several hundreds of XBRL-files automatically and gather certain specific pieces of data and paste them into an excel sheet. I managed to get the "tangential code" working, but cannot answer the core question.
E.g., in the XBRL file I need the value of this fact, reported against the concept pfs:GainLossBeforeTaxes:
<pfs:GainLossBeforeTaxes
unitRef="U-EUR"
decimals="INF"
contextRef="CurrentDuration">1091134.68</pfs:GainLossBeforeTaxes>
==> I need to obtain 1091134.68
This is doubtlessly something which is easy with Regex, but I cannot seem to get this working. And time constraints are also a thing for me, so I would like to obtain some sort of minimal viable product so far and later on expand that, but at this point the code is more of a means to an end, rather than the endproduct (analysis) itself.
So far, I came up with the following:
Sub EDI_Input()
Dim myFile As String
Dim textline As String
Dim StartPos As Integer
Dim EndPos As Integer
myFile = Application.GetOpenFilename()
Open myFile For Input As #EDI
Do Until EOF(EDI)
Line Input #EDI, textline
If InStr(textline, "NonRecurringFinancialCharges") <> 0 And InStr(textline, "CurrentDuration") <> 0 Then
Endpos = InStr(textline, "</pfs:NonRecurringFinancialCharges><")
result = Left(textline, Endpos - 1)
StartPos = InStr(textline, "Char(34)&CurrentDuration&Char(34)&>")
textline = Left(textline, StartPos + 18)
Debug.Print (textline)
End If
Loop
I keep stumbling on the "invalid call procedure or argument error", possible because I load to many data in my string.
Anybody who has any opinion on how to get at least a partially working programma - in that way I can at least partially start my analysis - Or a tutorial for beginners/experience with this problem?
Welcome to StackOverflow!
I recommend using an XBRL processor, for example Arelle, which is open source. If I correctly remember, you should be able to export facts to formats like CSV and import it into Excel.
Otherwise, you will end up reimplementing an XBRL processor in VBA. There are many involved details to consider in order to get the correct values (joining with context, considering dimensions, etc). Values could be reported against a concept for multiple periods, etc.
An XBRL processor will do that out of the box.

Excel TEXT(dd.mm.yyyy) function and different client languages

How can I make a function with a formatted date that will work in every language? I want to make the following function:
=CONCATENATE(TEXT(C8;"TT.MM.JJJJ");"/";G8)
The problem here is, that I use the english client but because I'm a german, excel forces me to use T for day and J for year. I think this will cause problem on a PC located in england (for example).
I think [$-409] won't work because I still have to use T for day and J for year. Is there a good solution for this (function wise)?
If you pass the value of a formula in "" then it cannot be changed based on the localisation settings.
A good way to do it is to use a custom function with VBA, returning "TT.MM.JJJJ" if you are in Germany and "DD.MM.YYYY" if you are in England.
Public Function CorrectString() As String
Select Case Application.International(XlApplicationInternational.xlCountryCode)
Case 1
CorrectString = "DD.MM.YYYY"
Case 49
CorrectString = "TT.MM.JJJJ"
Case Else
CorrectString = "ERROR"
End Select
End Function
Would allow you to call the function like this:
=CONCATENATE(TEXT(C8;CorrectString());"/";G8)
And depending on the excel language, it would give either the German or the English versions.
To simplify the formula, try calling only:
=TEXT(21322;CorrectString())
This should return 17.05.1958.
Source for the regional languages, mentioned by #Dan at the comments:
https://bettersolutions.com/vba/macros/region-language.htm
Or run this to see the corresponding number of your current Excel:
MsgBox xlApplicationInternational.xlCountryCode
Just dropping in another imho elegant (VBA free) alternative taken from: Stackoverflow answer by #Taosique
=IF(TEXT(1,"mmmm")="January",[some logic for English system],[some logic for non-English system])
I've had the same problem and solved it with similar VBA Function. My function accepts input in international format, and outputs the local version for user.
Please see code below:
Function DateFormater(sFI As String)
Dim aFI() As String
aFI = split(StrConv(sFI, vbUnicode), Chr$(0))
ReDim Preserve aFI(UBound(aFI) - 1)
For i = 0 To UBound(aFI)
Select Case (aFI(i))
Case "m", "M"
DateFormater = DateFormater & Application.International(xlMonthCode)
Case "y", "Y"
DateFormater = DateFormater & Application.International(xlYearCode)
Case "d", "D"
DateFormater = DateFormater & Application.International(xlDayCode)
Case Else
DateFormater = DateFormater & aFI(i)
End Select
Next i
End Function
A simpler solution is to use generic Excel functions.
=CONCATENATE(TEXT(DAY(C8;"00");".";TEXT(MONTH(C8);"00");".";YEAR(C8);"/";G8)

A more efficient way of performing a multiple price changes function

I've been wondering if there is a more efficient, and probably neater way of performing an amateur function that I've just coded:
Public Function JanApr_prices()
'catalogue price changes
With ThisWorkbook.Worksheets("catalogue").ListObjects(1)
.DataBodyRange(44, 4).Value = 4.8 'Product A
.DataBodyRange(52, 4).Value = 4.5 'Product B
.DataBodyRange(77, 4).Value = 6 'Product C
.DataBodyRange(79, 4).Value = 9 'Product D
End With
End function
This basically changes prices for a set number of months when I'm doing some accounting. While it works, it definitely has its drawbacks because if I ever changed the relative position of the entries on the table, the price changes would probably go to the wrong place. So I'm in need of another idea, perhaps using a combination of .cells and match? I like to do things neatly and all the solutions that I've thought up so far are rather ponderous. Any suggestions would be greatly appreciated!
Feel free to edit the post title, I really did not know how to describe my problem!
The following code is not complete and will have to be adjusted to your needs. It is merely ment to show you the basic concept of the solution I propose.
Public Function JanApr_prices()
Dim vArr As Variant
Dim lCount As Long
vArr = ThisWorkbook.Worksheets("catalogue").ListObjects(1).Range.Value2
For lCount = LBound(vArr) To UBound(vArr)
Select Case vArr(lCount, 1)
Case "Produkt A"
vArr(lCount, 2) = 4.8
Case "Produkt B"
vArr(lCount, 2) = 4.5
Case "Produkt C"
vArr(lCount, 2) = 6
Case "Produkt D"
vArr(lCount, 2) = 9
End Select
Next lCount
ThisWorkbook.Worksheets("catalogue").ListObjects(1).Range.Value2 = vArr
End Function
The above code was taken from this website and slightly adapted:
https://fastexcel.wordpress.com/2011/05/25/writing-efficient-vba-udfs-part-1/
While I do not like to copy code from the web, StackOverflow prefers to be self-contained without the need to external references. So, there you go.

What does the number in the AddChart2 VBA macro represent?

I've use my Excel 2013 to record a macro in inserting a chart, a column-clustered chart in my case. In the view code option, it shows me a line of code as below:
ActiveSheet.Shapes.Addchart2(286,xl3DColumnClustered).Select
Please help me as I cannot understand what does the number 286 represent. I know the syntax of Addchart2 is:
expression.AddChart2(Style,XlChartType,Left,Top,Width,Height,NewLayout)
If I change the "286" to "285", the chart appears with a blue background. An error comes out if the number is 100.
Can anyone kindly tell me what does the number represent?
One can also provide only the ChartType and the application will use the default style.
Set oShp = ActiveSheet.Shapes.AddChart2(XlChartType:=xl3DColumnClustered)
oShp.Chart.SetSourceData Source:=RngDta
This picture shows the default ChartStyle for all ChartTypes (excluding StockHLC and StockVOHLC)
This won't directly answer your question, but it will help you figure out what is going on.
This is pure conjecture on my part, but I would guess it's an undocumented bitfield. As you may know a bit field is just a way to use a number. So image we have a Byte variable which can be 8 bits (or flags). So in a byte we can store up to 8 values.
Example: We have field called "DaysOpen" bits 1-7 mean the store is open on that day of the week. (We'll ignore the 8th bit.) So if the store is open M-F that would be binary 0111 1100.
Then you just convert that number to decimal and we see that it's 124.
That variable is a Variant so it could be anything from a Byte to Long meaning it could be storing up to 64 different flags.
As a side note (if you are interested) you can use bit fields like so:
Option Explicit
Public Enum DayFlags
'Notice these are power of 2.
dfSunday = 1
dfMonday = 2
dfTuesday = 4
dfWednesday = 8
dfThursday = 16
dfFriday = 32
dfSaturday = 64
End Enum
Sub Example()
Dim openHours As DayFlags
'Set the flags:
openHours = dfMonday Or dfTuesday Or dfThursday
'See the binary?
MsgBox Right$("00000000" & Excel.WorksheetFunction.Dec2Bin(openHours), 8)
'Notice the order is right to left. This is call endianness.
'You can check for a specific flag like this:
MsgBox IsOpenOnDay(openHours, dfMonday) & vbNewLine & IsOpenOnDay(openHours, dfFriday)
'You can add a flag like this:
openHours = openHours Or dfFriday
MsgBox IsOpenOnDay(openHours, dfMonday) & vbNewLine & IsOpenOnDay(openHours, dfFriday)
'You can remove a flag like this:
openHours = openHours Xor dfFriday
MsgBox IsOpenOnDay(openHours, dfMonday) & vbNewLine & IsOpenOnDay(openHours, dfFriday)
End Sub
Private Function IsOpenOnDay(ByVal openHours As DayFlags, ByVal day As DayFlags) As Boolean
IsOpenOnDay = ((openHours And day) = day)
End Function
Well , I had the same situation once, and those are basically chart styles. I tried to figure out the exact numbering but then i realized that recording was a much easier way of knowing the style numbers just as you have done here.
To answer you question, record macros to know which style you want to implement in your macros.
Just checking to see if 5 years later anyone has a better answer. I sure could use an enumeration of the chart styles; I don't like putting simple numbers in my code without some explanation as to what it means. Of course, I could use a comment, but if the numbers are documented, then that means they could change.
I found a partial list: https://learn.microsoft.com/en-us/office/vba/api/excel.xlcharttype
I'm sure these numbers, plus the bitfield variations as suggested by Pillgram above to control various other chart aspects, answer the question. The possible combinations are in the thousands, so a full list would be pretty useless. Recording is still your best bet.

Resources