Extracting table data from Outlook email body - vba

I am getting Outlook email, were the Body contains a Table consisting of several string Labels and associated string Text. I want to extract three Values associated with the respective Label. The first two searchs are one column right of the Label and the last one is one row below the Label.
I tried InStr() which works great for retrieving to the right of the Label, but it doesn't seem to work for the Value that is one cell below the Label.
Can I use MoveRight and MoveDown from Excel/Work inside the Outlook VBA or use "Range(Rng.Offset(0, 1).Address).Value" and "Range(Rng.Offset(1, 0).Address).Value" to select the Value to the right and below in Outlook VBA.
Key point here is that it is a structured table in the email body.

i have one email with a table that happens to be nested inside another table
that is why Tables(1).Tables(1) is used
the following code is for exploring the table.
first line highlights the cell in the table, so that you can check if you are referring the correct cell
the second and third lines shows how to get the value of a table cell
do not try to examine any range object in the watch window or the locals window. it causes outlook to crash. (no idea why)
if you want to explore any attributes of the range object then copy the email body to msWord. it does not crash when examining the range object
i could not find anything that refers to column headers
Sub aaaaa()
Application.Inspectors(1).WordEditor.Tables(1).Tables(1).Rows(1).Cells(1).Select
stop
Debug.Print Application.Inspectors(1).WordEditor.Tables(1).Tables(2).Rows(3).Cells(4).Range.Text
Debug.Print ActiveDocument.Tables(1).Tables(1).Cell(1, 1).Range.Text
End Sub

Related

How to create hyperlinks in VBA for mutiple cells?

I have to create hyperlinks for a list of variables to get easily to the datas in a database. My database contains summary of many variables coming from different sources. My problem is, I have to skip multiple rows fill with duplicates and blank cells. The number of rows to skip depends for every variable. I also want that my hyperlinks have the name of the variable from the database (example : Customer_Since). Is there a way to create a loop to skip the good number of rows and create a hyperlink? Example : if I click on the link named Customer_Since, it takes me to the row that contains the summary of the variable Customer_Since. Can somebody help me?
To create a hyperlink you can use this code:
ThisWorkbook.Sheets("SheetName").Hyperlinks.Add Anchor:=Range("A10"), Address:="", SubAddress:="Sheet2!B5", TextToDisplay:="Link"
where:
Anchor - cell, where there will be a hyperlink;
SubAddress - range to navigate to;
TextToDisplay - text in the link.
You can use another vba code with your rules to correctly insert Anchor`s range.
Or please provide more information and examples of the input and output data to get help.

Search xlsx for a value, if found replace with different value

So I'm either being too specific, or not searching well enough, because I can't find anything that answers my question. So I came here for help. Here is the situation:
I have an excel sheet, let's call it "CustomerCodeReference", that has a column (A) of Customer Codes (I.E. A2001, A2002, B3900, Q2838, etc, these are NOT necessarily in order) About 3000 of them, and in the next column over (B), I have the group that code represents (I.E. Accounts Primary, Accounts Secondary, Admin Group, User Group, just different names and etc.)
Now, from our company server I can export a spreadsheet of reports from customers, but the problem is, they are labelled by customer code, + a report serial number. The sheet exports as several columns, but one of the columns (G) contains the Customer code and serial number, and each row is a report, sometimes hundreds depending on the date range set. So keeping with the example, let's say it's a report from "Accounts Primary" It's labelled A2001234567 (where everything after the customer code of 'A2001' is the report serial number) sometimes, the report may be from several customers, so that column may have more than one code+SN in it per row.
Given that I have thousands of these codes and groups, is there some macro I can create that every time I export the spreadsheet of reports, I can maybe copy over the "CustomerCodeReference" sheet, and have it automatically search the column of customer codes and SNs, then either replace the code with the actual name, or place the actual name in another (empty) row further back. So I can basically easily reference whose report it is without having to look up the code each time?
I realize I will need to do this in VBA, as there is no formula I can think of that will work.
I have some pro's I think going for me:
-I already have the Master code list, so even though there are thousands of codes, they are all listed in Column A, and the actual name of group they reference is in column B.
-The codes are consistent, a letter, followed by 4 numbers, so always 5 characters long.
-When pulling the report, it always names the worksheet "Customer Reports" so it's easy to reference
These are constants. So I need the actual customer name to either replace the code (while leaving the serial number intact) or if easier, add the actual name to the next empty column on the same row. I also might need to share this with coworkers, so basically just send them the "CustomerCodeReference" sheet and when they add it to all their pulled spreadsheets, it does the same thing. (Macros will be enabled, so no worries there)
Is this too complicated an idea? or can I pull it off? Thanks in advance for the help!
EDIT: I apologize, I complete forgot to attach any sort of code. Here is what I have come up with in VBA, but not sure if I am on the right track as it does not complete the replacement, and I can't quite get it to add values in next available empty cell.
Sub replaceStringInCell()
'declaring my sheet I want to change change customer codes in
Dim CustomerCodes As Range
'declaring strings I will be replacing and with what I will be replacing them
Dim ReportNumbers As Range
Dim CustomerNames As Range
'identifying column I am working to replace, also trying to shoot for next empty column
Set CustomerCodes = PulledReports.Worksheets("Customer Reports").Range("G:G")
'specifying my strings
ReportNumbers = PulledReports.Worksheets("Customer Reports").Range("G:G")
myReplacementString = PulledReports.Worksheets("Customer Code Reference").Range("A:A")
'replace string in cell
CustomerCodes.Value = Replace(Expression:=CustomerCodes.Value, Find:=ReportNumbers, Replace:=CustomerNames)
End Sub
This should do the trick:
Sub stack_overflow()
Dim cust As Worksheet
Dim ref As Worksheet
Set cust = ActiveWorkbook.Worksheets("Customer Reports")
Set ref = ActiveWorkbook.Worksheets("Customer Code Reference")
'Finding next empty column
Dim column As Integer
column = cust.UsedRange.Columns.column + 1
'Filling this columns
For Each cell In cust.Range("G2:G" & cust.Cells(Rows.Count, "G").End(xlUp).Row)
cust.Cells(cell.Row, column).Value = Application.WorksheetFunction.VLookup(Left(cell.Value, 5), _
ref.Range("A2:B" & ref.Cells(Rows.Count, "B").End(xlUp).Row), 2, False)
Next cell
End Sub

Excel VBA - Pull information into user form to update

I am trying to create a userform that allows the users to update issues stored in a specific sheet (called Issues List). I have built a dropdown list using data validation that allows the user to select the unique issue name from a list. I have created a button next to that dropdown which opens up the userform and correctly imports the issue name identified from the dropdown.
What I need to figure out is, when the user form is initiated how do I have it search column B in my Issues List sheet and identify which row contains the issue selected by the user, and populate the fields of the user form with the information found in rows C-X of the Issues List sheet.
What I have been trying to use is an index match function, but have been unsuccessful in getting the code to work. An example of what I have been using is:
Resolved.Value = Application.WorksheetFunction.index
('Issue List'!$X$2:$X$1000,Application.WorksheetFunction.match
('Priority Table'!I35,'Issue List'!$B$2:$B$1000,0))
Any help would be greatly appreciated.
Thanks in advance!
When you use Worksheet Functions in VBA, you still have to pass in the ranges using VBA language:
So instead of:
'Issue List'!$X$2:$X$1000
you would use:
Worksheets("Issue List").Range("X2:X1000")
And instead of:
'Priority Table'!I35
Just use:
Worksheets("Priority Table").Range("I35")
Note that you can also refer to ranges by names, which can make coding easier and also far safer. When you insert rows in spreadsheets, Excel doesn't automatically update ranges in any VBA code. A reference to I35 will always to be I35.
Instead, define a name for cell I35 in Excel as normal, then refer to it in the code.
For example, if you name I35 as "Issue"
You can refer to the cell by:
Range("Issue")
(If it is a global variable, which it is be default as long as it's a unique name in the workbook, you don't need to use the Sheets("Priority Table") qualifier.
Refer to this documentation for more info on how to refer to ranges in Excel from VBA:
https://msdn.microsoft.com/en-us/library/office/gg192736(v=office.14).aspx

with a VBA userform, how do you populate a combobox with a different text and value?

I am trying to populate a VBA userform combobox with a named range, and I want the text value to display in the combobox for the user to select, but the value I want returned is the cell reference to the initial named range. That way it would point back to the named range, and if I change that text, it would automatically update all the references I have on the sheet that were entered by the form.
Right now I can get the named range to populate the combobox by iterating through the range, and using an .AddItem to give it the textual value, but then it just dumps that textual value into my spreadsheet, when instead I would like it to have the cell reference from the range that populated it.
The easiest way to do this is to create an Array(X,2) X being the number of items in the array. Then you put the String you want to display in Array(1,1) and the data you want in Array(1,2) then simply populate the combo box like normal. When you and use the array to reference which item they choose. They choose item 8, you know it is Array(8,2) If you need more help please post some code.
So, after more research it would seem that I am unable to directly accomplish what I want with the combobox. I ended up just looping through the range to fill the combobox with the textual values, and then when I submit the form, I looped through the same range of values, checked it if the submitted value matches one from the range of values, and if it does, then return the .Address instead of the .Value, and that gave me the cell reference I was looking for. Too bad the combobox doesn't work more like a real html select menu, it would have made my life a little easier, but in the end I was able to make it work, it just isn't as clean as I would have liked.

How do I access one entry in a mail merge document?

I have set up a mail merged XtraReport, and it works fine. Now I want to access one entry in that mail merged report. By entry I mean the text associated with one row in the dataset, i.e. with the values filled in instead of having the square brackets with the field names.
So if have an XRRichText in my report with the text "Hi [name]" I want access to the XRRichText object with the RTF value "Hi Sandy"
Edit: Added information in example, added VB.net tag
Try the GetCurrentColumnValue method described here.