VBA Outlook 2010. Extracting specific outlook body text to excel - vba

There are a few posts open on this topic however none seem to fully do what I need. I have done a little bit of programming however I have never done anything with VBA. Every day I receive a series of emails varying from 10 to 50 all containing a subject line starting with [Tk#*******] New Request ( * = 7 digit number)
Then inside the body text there is a form that looks like this:
Body Text
I then have an excel sheet set up with 'Username' in 'C', 'Company' in 'G', 'valid until' in 'H' and 'Ticket' in 'I'. I would like to extract first the 7 digit ticket number from the subject and put it in the excel 'Ticket' field, then just the 'smithjoh' part from the login field and place it in 'Username', then the External company listed to 'Company' and finally the Expiration date into 'valid until'.
First I would like to know if this is possible to do as it is extracting specific sections of the data and if so if someone could help me out with making this work that'd be most appreciated. I have attempted to do it myself however lack of experience has left me clueless therefor there is nothing to work with unfortunately. If this could be made it would help me out a lot as it would automate a very tedious manual task.
Thanks,
Mark

Ok, if you are grabbing the body and title without issue then you just need to do string manipulations. Read them into a variable each. Assuming that your subject is litterally "TK#******* New Request" then this should get you started. Basically repeat this logic for each part you want to pull out. Once you have the values in variables you can then put those values into cells.
Dim sSubject as string
Dim sBody as string
Dim sTicket as string
Dim sLogin as string
Dim lLoginPos as long
Dim iLoginLength as integer
sTicket = Mid(sSubject,4,7) 'start 4th char and grab 7 ... if you actually have the brackets in the subject then do 5,7
lLoginPos = InStr(sBody, "emea") + 5 'if they aren't all emea you will need to key off the "Req on behalf name" and add more to the result the result will be the e in emea so add 5 to get past that to the login.
iLoginLength = InStr(sBody, "Req on behalf mail") - lLoginPos ' you might need to subtract an additional 1 or 2 if your result isn't perfect. Not sure what the blank white spaces in your screenshot will do here.
sLogin = Mid(sBody,lLoginPos,iLoginLength) ' grabs that username.
With Sheets("Sheet1")
cells(1,3) = sLogin ' puts that into Row 1 Colum 3 (C) Cells is R1C1 ... backwards from the normal way you think of excel
End With
Use other string variables for all the other parts you want to grab and just repeat the logic of finding the starting place and ending place and then using mid to put it into a variable.
Give it a shot filling out the rest and if you get stuck, post your code up to that point and let us know what line is giving you trouble. Don't forget to turn on your locals window and use your F8 key to step through the code one line at a time so that you can see exactly what is going on. This is especially useful with string manipulations.

Related

Attaching specific files based on the user's selection in a userform

For the next part of this project that I've been working on to speed up follow up emails to clients for the office, I'm looking to grab a specific attachment from a specified filepath based on the items that the user selected on the userform. These emails will always be sending the exact same files so the less time the user has to spend manually attaching files, the better it will be. My first assumption right off the bat was that I'd need a loop to do this, so I began to do my groundwork, but now I'm generally stuck.
The first loop grabs what the user selected from the userform:
For i = 0 To List1.ListCount - 1
If List1.Selected(i) Then
Counter = Counter + 1
msg = msg & "<font style = 'background: yellow'>" & List1.List(i) & "<br />"
Else: If Counter = 0 Then End
End If
Next
And the second loop attaches the files based on the selections above:
For i = 0 To List1.ListCount - 1
If List1.Selected(i) Then
Counter = Counter + 1
.Attachments.Add List1.List(i)
Else: If Counter = 0 Then End
End If
Next
The attachments process just fine.However, the program ends up displaying the highlighted body of the message as the filepath I tried to associate with the list item:
' test files
List1.List(0) = "C:\Users\jmarkman\Dropbox\Python Practice\ex1.py"
List1.List(1) = "C:\Users\jmarkman\Dropbox\Python Practice\ex2.py"
List1.List(2) = "C:\Users\jmarkman\Dropbox\Python Practice\ex3.py"
List1.List(3) = "C:\Users\jmarkman\Dropbox\Python Practice\ex4.py"
List1.List(4) = "C:\Users\jmarkman\Dropbox\Python Practice\ex5.py"
List1.List(5) = "C:\Users\jmarkman\Dropbox\Python Practice\ex6.py"
So my question is, how do I associate these file paths with corresponding items in the listbox within the userform? I'm pretty sure that although it worked, the process changed the list items since I assigned them a different value.
I'm not sure how complex or simple this might end up being, so your time and patience are well appreciated.
People have said that one can learn best just by doing and making mistakes, but let me tell you that not having someone you can at least talk to about where to start making mistakes is incredibly frustrating. I hope anyone else who, like me, was on the cusp of solving this problem is able to look here and have their own "a-ha!" moment.
When I first asked this question, I was on the right path with choosing to put all of my filepath locations within an array and I was further along the right path by using a loop to go through it. I declared the myAttach array with a range as I did at first, but unlike whatever example I saw during my google research, I kept my second attachment loop the same but simply changed out List1.List(i) for myAttach(i). That made the script's wheels turn and performed all the functions I needed it to.
The long and short of it was that I made an array that matched the quantity and order of the items in the userform and re-used the loop I made for picking the subjectivities, I was able to associate the choices in the userform to those in the array by having the second loop go through the array. Each listing in the array had a filepath associated with it.
' example
myAttach(0) = "[filepath]"
myAttach(1) = "[filepath]"
myAttach(2) = "[filepath]"
myAttach(3) = "[filepath]"
' ... and so on ...
It helped to visualize the array and the list items as two side-by-side columns; the first item in the list is parallel to the first item in the array, and can therefore be recognized by the second loop. If a mental image isn't forthcoming, try inputting some data into two or more Excel columns to witness the relationship or review Matricies.
A caveat of this line-up approach, I found out shortly after while continuing research to figure out exactly what I did right this time would be if I had to have the items in the list in a specific order (i.e., alphabetical), but fortunately the list items are phrases and complete sentences and don't require sorting.
Happy learning and programming!

Remove dot´s from date

I made a program that generates a daily index code.
It gets created from
Employer (everyone has a number from 0-9)
Date of serial code requested
Everything is working fine, but I wannt to remove the dots from the date
I tried things like
date.Text = date.Text.Replace(".""", """")
or
Dim clean as String
clean = myString.Replace(".", "")
But nothing happens
May be I just didnt unterstand the using... If yes, so please help me to find a alternative.
Ok i will try to explain better.
As I lunch it a textbox gets the date of today, the textbox is called date
Ive got a combobox, from there you select the employer. Every employer has a number. For example Andreas is Number 1.
I wannt to do something like:
if combobox1.text = "Andreas" then
dailyCode.text = "1" & date.text
end if
My problem is that the date is written with dots, the daily code should not have dots.
Sorry for my bad English
In your questions Details are still incomplete.still assuming that the date(still i am confused how are you using reserved keyword) is declared as date type itself,consider formatting it with Format function itself.
Try using
Dim s As String = Format(date, "ddMMMyyyy")
hope that helps.

VB.net Find And Replace from Data in a DataGridView in a text file

Im sure someone out there can help, im totally new to coding but getting into it and really enjoying. I know this is such a simple question out there for you folks but i have the following, I load a spread sheet of strings (2 columns) into a datagridview the reason i do this because there is over 100,000 find and replaces and these will generally sit within and existing string when searching, then from there i want to simply search a txt file and find and replace a number of strings in it. So it would check each row in a datagrid take from column 1 the find and use column 2 to replace then outputs the string to another txt file once the find and replace has taken place. My current results are that it just takes what was in the first file and copies without replacing in the second find.
Any assistance is gratefully received, many thanks.
Please see below my amateur code:-
Private Sub CmdBtnTestReplace_Click(sender As System.Object, e As System.EventArgs) Handles CmdBtnTestReplace.Click
Dim fName As String = "c:\backup\logs\masterUser.txt"
Dim wrtFile As String = "c:\backup\logs\masterUserFormatted.txt"
Dim strRead As New System.IO.StreamReader(fName)
Dim strWrite As New System.IO.StreamWriter(wrtFile)
Dim s As String
Dim o As String
For Each row As DataGridViewRow In DataGridView1.Rows
If Not row.IsNewRow Then
Dim Find1 As String = row.Cells(0).Value.ToString
Dim Replace1 As String = row.Cells(1).Value.ToString
Cursor.Current = Cursors.WaitCursor
s = strRead.ReadToEnd()
o = s.Replace(Find1, Replace1)
strWrite.Write(o)
End If
Next
strRead.Close()
strWrite.Close()
Cursor.Current = Cursors.Default
MessageBox.Show("Finished Replacing")
End Sub
1. What you are doing is :
creating a StreamReader whose purpose is to read chars from a File/Stream in sequence.
creating a StreamWriter whose purpose is to add content to a File/Stream.
then looping
a) read the remaining content of file fName and put it in s
b) replace words from s and put the result in o
c) add o to the existing content of the file wrtFile
then the usual closing of the stream reader/writer...
But that doesn't work because, on the secund iteration of the loop, strRead is already at the end of your loaded file, then there is nothing to read anymore, and s is always an empty string starting from the secund iteration.
Furthermore, because s is empty, o will be empty aswell.
And last of all, even if you manage to re-read the content of the file and replace the words, strWrite will not clear the initial content of the output file, but will write the resulting replaced string (o) after the previously updated content of the file.
2. Since you loaded the content of the file in a string (s = strRead.ReadToEnd()), why don't you :
load that s string before the For-Next block
loop the datagridview rows in a For-Next block
replace using the pair Find1/Replace1 s = s.Replace(Find1, Replace1)
then, save the content of s in the targeted file outside the For-Next block
3. However, improving your understanding of how streams work, what should be considered and what are forbidden is a bit outside the scope of SO I think; such documentation could be found/gathered on the MSDN page or with the help of your friend : google. The same applies for finding out/thinking of how you should arrange your code, how to achieve your goal.Let's take an example :
' Content of your file :
One Two Three Four Five Six
' Content of your DataGridView :
One | Two
Two | Three
Three | Four
Four | Five
Five | Six
Six | Seven
The resulting replacement text at the end of a similar routine as yours will be :
Seven Seven Seven Seven Seven Seven ' :/
' while the expected result would be :
Two Three Four Five Six Seven
And that's because of the iteration : already replaced portions of your file (or loaded file content) could get replaced again and again. To avoid that, either :
split the loaded content in single words, and use a "replaced" flag for each word (to avoid replacing that word more than once)
or preload all the pair Find/Replace, and parse the file content in sequence once, replacing that instance when required.
So, before using an interesting object in the framework :
you should know what it does and how it behaves
otherwise -> read the documentation
otherwise -> create a minimalistic test solution which purpose is to brute force testings on that particular object to debunck all its powers and flaws.
So, like I said in 2., move those ReadAllText() and Write() outside the For/Next block to start from and have a look at the resulting output (Ask specific questions in comments when google can't answer) Then if you're OK with it even if issue like the One Two Three example above could occur, then voila ! Otherwise, use google to gather more examples on "splitting text in words" and reformating the whole, have some tries, then get back here if you're stuck on precise issues.

What am I doing wrong when splitting lines from a textfile

I am working on a quiz for my computer science program and the idea is having keywords and definitions. The User will be shown a keyword that gets randomized and three definitions in radiobuttons, one must be the correct answer.
I decided to put my keywords and my defintions in the same file like so:
Keyword1 = Definition1
Keyword2 = Definition2
Keyword3 = Definition3
etc.
On my main form I have the following loop:
For Each line As String In System.IO.File.ReadAllLines("my-file-path-here")
Dim Pair() As String = line.split("=")
LabelKeyword.text = Trim(Pair(0)) ' Needs Randomizing
RadioButtonDef1.text = Trim(Pair(1)) ' Needs randomizing
'RadioButtonDef2.text = 'Don't know needs randomizing
'RadioButtonDef3.text = 'Don't know needs randomizing
Next
What I can't seem to figure out is how to randomize the keywords and the definitions. Also I have 15 lines in my text file and it always seems to only read the last line.
So my questions are:
How can I randomize the keywords and the definitions always having one of the definitions the answer to the current keyword.
Why does it only read the very last line of my text file and how can I fix it?
I also need to be able to make the quiz only finish when every keyword has been matched to its definition twice. Their time taken also needs to be recored as they play.
You are looping through all of the lines in your text file, but you are displaying all of them in the same control. Therefore, each time you iterate through the loop, it overwrites the values in the controls from the last iteration. I would strongly suggest storing your values in some sort of data-structure in memory. Then you can access the values randomly at will. For instance, you could store all the values in a Dictionary, like this:
Dim dict As New Dictionary(Of String, String)()
For Each line As String In File.ReadAllLines("...")
Dim pair() As String = line.Split("=")
dict(pair(0)) = pair(1)
Next

Adding a hyperlink in word, with vb.net

I'm currently trying to add a hyperlink to a web url in word through a VB program. I'm stumbling around to try and find the proper syntax and what I need to accomplish this, because I've been getting a lot of unhelpful VBA examples, which is not what I need at all.
My code looks like this:
sPara2 = oDoc.Content.Paragraphs.Add
sPara2.Range.Text = attachmentRdr("attachmentName")
sPara2.Range.Hyperlinks.Add(attachmentRdr("attachmentPath"))
sPara2.Format.SpaceAfter = 24 '24 pt spacing after paragraph.
sPara2.Range.InsertParagraphAfter()
where attachmentRdr is a sqlDatareader reading strings of text (attachment name, and path) from a database. If I run this, I get an error for bad parameters (which gets' proced off of the hyperlinks.add()).
Pass range through as the first parameter to the Add function, followed by your URL:
Dim range As Microsoft.Office.Interop.Word.Range
range = Me.Application.Selection.Range
range.Hyperlinks.Add(range, "http://www.microsoft.com")