I'm looking to find a way to remove stop words using a function in Visual Basic inside my Access DB.
Today I'm just doing several replace but I know it's not the right way as I wouldn't know if I'm removing the Stop Word as a word or within a word.
Any help would be great, I just cannot find any way to do this on VB.
Okay, you mean something like this, right?
OutputString = Replace("They answered the question", "the", "")
This replaces all occurrences of "the" from the phrase, including part of the word "They".
The simplest solution would be to put spaces before and after the word to replace:
OutputString = Replace("They answered the question", " the ", "")
This works for the phrase in my above example, but it won't work when the word occurs at the beginning or at the end of the phrase.
For these cases, you need to do more. Something like this:
Public Function RemoveStopWords( _
ByVal Phrase As String, _
ByVal WordToRemove As String _
) As String
Dim RetVal As String
Dim Tmp As String
'remove the word in the middle of the phrase
RetVal = Replace(Phrase, " " & WordToRemove & " ", " ")
'remove the word at the beginning
Tmp = WordToRemove & " "
If Left(RetVal, Len(Tmp)) = Tmp Then
RetVal = Mid(RetVal, Len(Tmp) + 1)
End If
'remove the word at the end
Tmp = " " & WordToRemove
If Right(RetVal, Len(Tmp)) = Tmp Then
RetVal = Left(RetVal, Len(RetVal) - Len(Tmp))
End If
RemoveStopWords = RetVal
End Function
This works as long as the words in the phrase are always separated with blanks.
When there can be other separators than blanks, you have to do even more.
For example, instead of hardcoding the blanks in the function, you could loop over a list of separators and execute the function for each one.
I won't show this as code now, but you get the idea.
Related
I've been working on a spread sheet to allow my team to manage our workload more effectively, whilst the business is developing a new tool. Anyway, what the sheet does is inject information, then at the click of a button, it populates an OFT email template so that the info can be sent out.
Problem is, we rely heavily on bullet lists for our emails, and I'm really struggling to find a way of adding bullets effectively from an ActiveX Textbox.
At the moment, I have a button which adds the follow to a text box:
[bullets]
* Bullet 1
* Bullet 2
* Bullet 3
[/bullets]
I then have Replace statements that look for strings and it replaces them with the appropriate HTML tags. Here's the code:
' Add HTML formatting to text updates so it displays correctly in the email.
LatestUpdate.Text = Replace(LatestUpdate, "[bullets]", "<ul>")
LatestUpdate.Text = Replace(LatestUpdate, "[/bullets]", "</ul>")
LatestUpdate.Text = Replace(LatestUpdate, "* ", "<li>")
LatestUpdate.Text = Replace(LatestUpdate, vbCrLf, "<br>")
The problem I'm having, is that non-technical people are using this document, so I would really like to have it in such a way were they don't have to look at the markup, but can simple add bullets straight from the textbox.
I was originally thinking about replacing "* " with "< li >" however, that doesn't add the correct < ul > tags, so it's not actually a bullet list within the email.
Can anyone help in simplifying this process for the end users please? I'm really stuck.
The holy grail would be to enable rich text formatting on the textbox, but I don't believe that's possible from all the research I've done?
TIA.
Based on your last comment, what you are looking for is not just a bullet point in your textbox but indentation as well. So here is an attempt at it:
First add the below in your <textbox>_KeyUp function:
Private Sub txtBulletPoints_KeyUp(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
Dim STRING_LENGTH As Long: STRING_LENGTH = 49
Dim aLine() As String
Dim aLineSpace() As String
Dim iC As Integer
Dim sText As String
Dim bUpdate As Boolean
' Only do this if there is a string to work with
If Len(Me.txtBulletPoints.Text) > 0 Then
' Set initial values
aLine = Split(Me.txtBulletPoints.Text, vbCrLf)
bUpdate = False
' First lets indent the last line if we need to
If Left(aLine(UBound(aLine)), 2) = "- " Then
For iC = LBound(aLine) To UBound(aLine)
If iC = UBound(aLine) Then
sText = sText & vbTab & aLine(iC)
Else
sText = sText & aLine(iC) & vbCrLf
End If
Next
Me.txtBulletPoints.Text = sText
End If
' Now the tricky bit. Check if we have reached the end of the
' line so that we can indent the text into the next line
If (Len(aLine(UBound(aLine))) >= STRING_LENGTH) And (InStr(1, aLine(UBound(aLine)), vbTab) = 1) Then
For iC = LBound(aLine) To UBound(aLine)
If iC = UBound(aLine) Then
aLineSpace = Split(aLine(iC), " ")
' As we have to indent the last bullet point line, call the finction to do that
sText = sText & SetIndentsInString(aLine(iC), STRING_LENGTH)
Else
sText = sText & aLine(iC) & vbCrLf
End If
Next
Me.txtBulletPoints.Text = sText
End If
End If
End Sub
Now add the below UDF where your form code is (essentially at the same place where your <textbox>_KeyUp function is):
Function SetIndentsInString(ByVal sString As String, ByVal iIndentLen As Long) As String
Dim iC As Long
Dim iLastTab As Long: iLastTab = 0
Dim aSpace() As String
Dim aTab() As String
Dim sCurString As String
' Check if the string is the same as what it was last
' time (sLastString is a private module variable initialised
' to "" when the form is activated)
If Replace(sString, vbTab, "") = Replace(sLastString, vbTab, "") Then
' Its the same string so lets return it as is
SetIndentsInString = sString
Else
' Its not the same string so set initial values
sLastString = sString
SetIndentsInString = ""
' Loop to see how many lines we have based on number of TABs in the string
Do While InStr(iLastTab + 1, sString, vbTab) > 0
iLastTab = iLastTab + InStr(iLastTab + 1, sString, vbTab)
Loop
' If there is only 1 TAB, simply indent the line
If iLastTab = 1 Then
aSpace = Split(sString, " ")
SetIndentsInString = Mid(sString, 1, Len(sString) - Len(aSpace(UBound(aSpace)))) & vbTab & " " & aSpace(UBound(aSpace))
Else
' More then 1 TAB.. damn!. Ok well lets work it
aTab = Split(sString, vbTab)
sCurString = aTab(UBound(aTab))
' Check if the last line of our bullet point has more characters then allowed in a line
If Len(sCurString) >= iIndentLen Then
' It does. Now loop through all the lines in our bullet point and set the last character in a new line with indent
aSpace = Split(sCurString, " ")
For iC = LBound(aTab) To UBound(aTab)
If iC = UBound(aTab) Then
SetIndentsInString = SetIndentsInString & Mid(sCurString, 1, Len(sCurString) - Len(aSpace(UBound(aSpace)))) & vbTab & " " & aSpace(UBound(aSpace))
Else
SetIndentsInString = SetIndentsInString & aTab(iC) & vbTab
End If
Next
Else
' It doesnt. Loop through and send the string back
SetIndentsInString = sString
End If
End If
End If
End Function
Now in the same module, make the following declaration at the top:
Private sLastString As String
Essentially the above will act like a bullet point as it would be in a Rich Text box. Things to remember is that you will have to set STRING_LENGTH to the number of characters your textbox will take in a given bullet point line (you will have to play around with that). Below is a screen print of how it worked for me
//:celebrity/:channel[:id='239']/:linear/:schedules[:scheduleId='TV_239_2036-05-11_03:00:00.000' and :startTime='2036-05-11T03:00:00.000+0000']/:authorization[:linearAuth='false' and :linearSubAuth='false' and :authCode='NA']
I have one column with multiple XPaths. I need JSON version for this so I need to delete all colon characters (:) but not in dates (not in scheduleId and startTime). It means delete them only when before colon is: "/" or "[" or " "
How to do that using VBA code? Thanks
Assuming you are working in Column A ,try this:
Sub Demo()
Columns("A:A").Replace What:="/:", Replacement:="/", LookAt:=xlPart
Columns("A:A").Replace What:="[:", Replacement:="[", LookAt:=xlPart
Columns("A:A").Replace What:=" :", Replacement:=" ", LookAt:=xlPart
End Sub
EDIT1: Code based on the comment
Sub Demo()
i = WorksheetFunction.Match("iXpath", Range("A1:Z1"), 0)
Columns(i).Replace What:="/:", Replacement:="/", LookAt:=xlPart
Columns(i).Replace What:="[:", Replacement:="[", LookAt:=xlPart
Columns(i).Replace What:=" :", Replacement:=" ", LookAt:=xlPart
End Sub
Here, I am searching for iXpath in the range A1:Z1, you can change this range as required.
EDIT2: Code to work on all worksheets
Sub Demo()
Dim ws As Worksheet, i As Long
For Each ws In ThisWorkbook.Worksheets
With ws
i = WorksheetFunction.Match("iXpath", .Range("A1:Z1"), 0)
.Columns(i).Replace What:="/:", Replacement:="/", LookAt:=xlPart
.Columns(i).Replace What:="[:", Replacement:="[", LookAt:=xlPart
.Columns(i).Replace What:=" :", Replacement:=" ", LookAt:=xlPart
End With
Next
End Sub
Try this...
"MyString" is the string with your content
"MyReplacer" is what shoud replace the colons (can be space, nothing or any other character)
MyString = "//:celebrity/:channel[:id='239']/:linear/:schedules[:scheduleId='TV_239_2036-05-11_03:00:00."
MyReplacer = " " 'here add what must replace the ":"
MyString = Replace(MyString," :",MyReplacer)
MyString = Replace(MyString,"[:",MyReplacer)
MyString = Replace(MyString,"/:",MyReplacer)
You could also do something like this. I based this on the input shown, so the position of the = may change, there are 2 in the example.
Function testReplace(strInput As String) As String
testReplace = Join(Split(strInput, ":"), "") & "=" & Split(strInput, "=")(2)
End Function
I've come up with a bit of a weird situation. I have a string that was entered into a form from a webpage. I noticed that the string wasn't behaving as expected when I was trying to apply a filter.
The crux of the matter is depending on how I view the string it appears differently.
Form View - "523548"
Datasheet View - " 523548"
Raw Sql - " 523548"
Actually, when I view the datasheet value it appears as "523548 " but copies as " 523548".
Asc(Left(string),1) tells me the first character is Chr9 (Tab Key)
I am really stuck to find out why this is happening or more importantly, what I can do to correct it.
Thanks!
Dave.
I'd use the Trim() function here. Although the link is for Excel, it's the same syntax in Access.
Use this function when you write the value to the table, and you can use this function to clean up your current data as well. This should remove phantom tabs, as well as spaces.
Thanks for the tips. I found this function and added in a couple of items to suit my needs.
' Strip Illegal Characters
' http://www.utteraccess.com/wiki/index.php/Strip_Illegal_Characters
' Code courtesy of UtterAccess Wiki
' Licensed under Creative Commons License
' http://creativecommons.org/licenses/by-sa/3.0/
'
' You are free to use this code in any application,
' provided this notice is left unchanged.
'
' rev date brief descripton
' 1.0 2010-10-23 Writing files to disk that contain illegal file characters can cause sometimes obscure error message(s)
'
Public Function fStripIllegal(strCheck As String, Optional strReplaceWith As String = "") As String
On Error GoTo StripIllErr
'illegal file name characters included in default string are ? [ ] / \ = + < > :; * " , '
Dim intI As Integer
Dim intPassedString As Integer
Dim intCheckString As Integer
Dim strChar As String
Dim strIllegalChars As String
Dim intReplaceLen As Integer
If IsNull(strCheck) Then Exit Function
strIllegalChars = "?[]/\=+<>:;,*" & Chr(34) & Chr(39) & Chr(32) & Chr(9) 'add/remove characters you need removed to this string
intPassedString = Len(strCheck)
intCheckString = Len(strIllegalChars)
intReplaceLen = Len(strReplaceWith)
If intReplaceLen > 0 Then 'a character has been entered to use as the replacement character
If intReplaceLen = 1 Then 'check the character itself isn't an illegal character
If InStr(strIllegalChars, strReplaceWith) > 0 Then
MsgBox "You can't replace an illegal character with another illegal character", _
vbOKOnly + vbExclamation, "Invalid Character"
fStripIllegal = strCheck
Exit Function
End If
Else 'only one replacement character allowed
MsgBox "Only one character is allowed as a replacement character", _
vbOKOnly + vbExclamation, "Invalid Replacement String"
fStripIllegal = strCheck
Exit Function
End If
End If
If intPassedString < intCheckString Then
For intI = 1 To intCheckString
strChar = Mid(strIllegalChars, intI, 1)
If InStr(strCheck, strChar) > 0 Then
strCheck = Replace(strCheck, strChar, strReplaceWith)
End If
Next intI
Else
For intI = 1 To intPassedString
strChar = Mid(strIllegalChars, intI, 1)
If InStr(strCheck, strChar) > 0 Then
strCheck = Replace(strCheck, strChar, strReplaceWith)
End If
Next intI
End If
fStripIllegal = Trim(strCheck)
StripIllErrExit:
Exit Function
StripIllErr:
MsgBox "The following error occured: " & err.Number & vbCrLf _
& err.Description, vbOKOnly + vbExclamation, "Unexpected Error"
fStripIllegal = strCheck
Resume StripIllErrExit
End Function
Well, adjust your routine to not include the tab for new entries.
The old entries you can adjust with Replace:
NewValue = Replace([OldValue], Chr(9), "")
I need to let users filter a continuous form using values the user enters into a textbox. And the continuous form is also nested within a couple levels of navigation subforms. This sounds easy enough, but all the examples I find on the web use macros instead of vba.
I set up the structure and wrote an AfterUpdate procedure for a textbox txtFilter as follows:
Private Sub txtFilter_AfterUpdate()
Dim filterval As String
filterval = txtFilter.Value
With Forms!Main!NavigationSubform.Form!NavigationSubform.Form
.Filter = "LastName Like " & filterval
.FilterOn = True
End With
End Sub
I have played with different syntax, but none of it seems to work properly. Here is a link to download the relevant parts of the database from a file sharing site: http://jmp.sh/v/HGctZ4Ru74vDAjzN43Wq
Can anyone show me how to alter this so that users can use the textbox to filter the continuous form?
I got it to work using this: .Filter = "LastName Like """ & filterval & """"
Need those annoying String Identifiers even for strings sometimes.
Okay, To get the form to open with no records and then pull up just the records you (or the user) specifies is easiest with a bit of re-work.
(I'd recommend you working with a copy and not your original)
1:On your Continuous Form, remove the Recordsource; we're going to use Late Binding (Kinda)
2:Then delete the code under the txtFilter box, then delete the box itself.
3:Add a comboBox with something like this as the recordsource:
SELECT DISTINCT myTable.LastName FROM myTable ORDER BY myTable.LastName; (This will get you a unique list of last names so knowing how to spell the name will not be necessary, plus it assures at least one match)
4:In the After Update event of that combobox, add code like this:
Dim strSource As String
strSource = "SELECT mt.IntakeNumber, mt.ClientNumber, " & _
"mt.LastName, mt.FirstName, mt.ConsultationDate " & _
" FROM myTable mt " & _
"WHERE (mt.LastName)= '" & Me.cboFilter.Value & "'"
Me.RecordSource = strSource
Me.Requery
Obviously you'll need to change the table and field names as necessary, but hopefully you get the idea.
Option Compare Database
Option Explicit '<- always include this!!!!!
Private Sub txtFilter_AfterUpdate()
Dim strFilter As String
' only set Filter when text box contains something
' to search for ==> don't filter Null, empty string,
' or spaces
If Len(Trim(Me.txtFilter.Value & vbNullString)) > 0 Then
strFilter = "LastName Like '*" & _
Replace(Me.txtFilter.Value, "'", "''") & _
"*'"
' that Replace() prevents the procedure from breaking
' when the user enters a name with an apostrophe
' into the text box (O'Malley)
Debug.Print strFilter ' see what we built, Ctrl+g
Me.Filter = strFilter
Me.FilterOn = True
Else
' what should happen here?
' maybe just switch off the filter ...
Me.FilterOn = False
End If
End Sub
I have built a report within MS Access which includes a short textbox that contains web addresses. The textbox has the "CanGrow" option set to "Yes".
Because there is limited horizontal space on the report for this field, and web addresses can be very long, rather than just having the web address spill over where ever the text length forces it to such as:
http://stackoverflow.com/que
stions/ask
I am wondering if there is a way to force the text string to word wrap at the last appropriate character, in this case the "/" character. The result would be something that looks more readable such as:
http://stackoverflow.com/
questions/ask
Can this be done? Any suggestions on how to approach this task?
The following recursive function will insert a carriage-return/line-feed based on user-defined characters and a max line length. This will work best with a fixed-width font, but with some experimentation should also be acceptable for a variable width font:
Function PrettyBreak(Txt As String, MaxCharsPerLine As Long, _
Optional BreakAfterChars As String = ":=-+&?./ ") As String
Dim t As String, i As Integer, Pos As Integer
If Len(Txt) > MaxCharsPerLine Then
t = Left(Txt, MaxCharsPerLine)
For i = MaxCharsPerLine To 1 Step -1
If InStr(BreakAfterChars, Mid(t, i, 1)) <> 0 Then
Pos = i
Exit For
End If
Next i
If Pos = 0 Then
PrettyBreak = t & vbCrLf & _
PrettyBreak(Mid(Txt, MaxCharsPerLine + 1), _
MaxCharsPerLine, BreakAfterChars)
Else
PrettyBreak = Left(t, Pos) & vbCrLf & _
PrettyBreak(Mid(Txt, Pos + 1), _
MaxCharsPerLine, BreakAfterChars)
End If
Else
PrettyBreak = Txt
End If
End Function
In use:
?prettybreak("http://stackoverflow.com/questions/5583986/ms-access-report-line-break-at-character", 30)
http://stackoverflow.com/
questions/5583986/ms-access-
report-line-break-at-character