Get just the 'text/plain' bit of a MIME email - vb.net

I'm working with parsing emails for a project i'm working on.
so far I connect to a pop3 mail server, download all of the mail thats there and loop through it getting the sender, subject and body.
I then decode the base64 body, which leaves me with a multi-part MIME message, like the following test email i sent myself...
I need to be able to split this Multipart MIME email body so that I can have one string which contains just the plain text version of the mail and another string which contains the html part.
I'm not interested in anything else the mail might have... attachments and suchlike can all get dropped.
Can anyone point me in the right direction?
If i'm going to be looking at using a 3rd party control, does anyone know of anything freeware that would be able to do this? I would never need to encode, just decode.

Assuming you have the headers in the email which you have extracted so that you can get the string used to identify the part boundaries in the email, you can get some way through the parsing with code like this:
Imports System.IO
Imports System.Text.RegularExpressions
Module Module1
Sub Main()
Dim sampleEmail = File.ReadAllText("C:\temp\SampleEmail.eml")
Dim getBoundary As New Regex("boundary=(.*?)\r\n")
Dim possibleBoundary = getBoundary.Matches(sampleEmail)
Dim boundary = ""
If possibleBoundary.Count = 0 Then
Console.WriteLine("Could not find boundary specifier.")
End
End If
' the boundary string may or may not be surrounded by double-quotes
boundary = possibleBoundary(0).Groups(1).Value.Trim(CChar(""""))
Console.WriteLine(boundary)
boundary = vbCrLf & "--" & boundary
Dim parts = Regex.Split(sampleEmail, Regex.Escape(boundary))
Console.WriteLine("Number of parts: " & parts.Count.ToString())
' save the parts to one text file for inspection
Using sw As New StreamWriter("C:\temp\EmailParts.txt")
For i = 0 To parts.Count - 1
' this is where you would find the part with "Content-Type: text/plain;" -
' you may also need to look at the charset, e.g. charset="utf-8"
sw.WriteLine("PART " & i.ToString())
sw.WriteLine(parts(i))
Next
End Using
Console.ReadLine()
End Sub
End Module
The email I used to test that did not have any base-64 encoding involved.

I would recommend using my free/open source MimeKit library to accomplish this task as opposed to using a regex solution.
I don't really know VB.NET, so the following code snippet might not be quite right (I'm a C# guy), but it should give you the general idea of how to accomplish the task you want:
Dim message = MimeMessage.Load ("C:\email.msg");
Dim html = message.HtmlBody;
Dim text = message.TextBody;
As you can see, MimeKit makes this sort of thing extremely trivial.

A = E1 = 80 =
= B8 = E1 = 80 = 80 = E1 = 80 = BC = E1 = 80-8A = E1 = 80 = BA; = 50 = 61 = 74 = 69 = 65 = 6E = 74 ;;
-PRINTABLE: = 50 = 61 = 74 = 69 = 65-6 E = 74 = 20 = E1 = 80 = 99 = E1 = 80 = 81 = E1 = 80 = 84 = E1 = 80 = BA =
E1 = 81 = 80 =
= E1 = 80 = 84 = E1 = 80 = BA = E1 = 80 = B8 = E1 = 80 = 80 = E1 = 80 = BC = E1 = 80 = 8A = E1 = 80 = BA
B = E1 = 80 = AD = E1 = 80 = AF; = 50 = 61 = 74 = 69 = 65 =
6E = 74 ;;
E1 = 80 = AF =
END: VCARD

Related

Beep sound at the end of multiple macros running

Can someone help with vba to have beep sounds a few times at the end of multiple macros running.
You can obtain a nice effect using the next class code. Firstly, insert a class module, name it clsMusic and paste the next code in it:
Option Explicit
#If Win64 Then
Private Declare PtrSafe Function Beep Lib "kernel32" _
(ByVal dwFreq As Long, ByVal dwDuration As Long) As Long
#Else
Private Declare Function Beep Lib "kernel32" _
(ByVal dwFreq As Long, ByVal dwDuration As Long) As Long
#End If
Enum Note
Ab7 = 3322.44
G7 = 3135.96
Gb7 = 2959.96
F7 = 2793.83
E7 = 2637.02
Eb7 = 2489.02
D7 = 2349.32
Db7 = 2217.46
c7 = 2093
B7 = 1975.53
Bb7 = 1864.66
A7 = 1760
Ab6 = 1661.22
G6 = 1567.98
Gb6 = 1479.98
F6 = 1396.91
E6 = 1318.51
Eb6 = 1244.51
D6 = 1174.66
Db6 = 1108.73
c6 = 1046.5
B6 = 987.767
Bb6 = 932.328
A6 = 880
Ab5 = 830.609
G5 = 783.991
Gb5 = 739.989
F5 = 698.456
E5 = 659.255
Eb5 = 622.254
D5 = 587.33
Db5 = 554.365
c5 = 523.251
B5 = 493.883
Bb5 = 466.164
A5 = 440
Ab4 = 415.305
G4 = 391.995
Gb4 = 369.994
F4 = 349.228
E4 = 329.628
Eb4 = 311.127
D4 = 293.665
Db4 = 277.183
c4 = 261.626
B4 = 246.942
Bb4 = 233.082
A4 = 220
Ab3 = 207.652
G3 = 195.998
Gb3 = 184.997
F3 = 174.614
E3 = 164.814
Eb3 = 155.563
D3 = 146.832
Db3 = 138.591
c3 = 130.813
B3 = 123.471
Bb3 = 116.541
A3 = 110
Ab2 = 103.826
G2 = 97.9989
Gb2 = 92.4986
F2 = 87.3071
E2 = 82.4069
Eb2 = 77.7817
d2 = 73.4162
Db2 = 69.2957
c2 = 65.4064
B2 = 61.7354
Bb2 = 58.2705
A2 = 55
Ab1 = 51.9131
G1 = 48.9994
Gb1 = 46.2493
f1 = 43.6535
E1 = 41.2034
Eb1 = 38.8909
d1 = 36.7081
Db1 = 34.6478
c1 = 32.7032
B1 = 30.8677
Bb1 = 29.1352
A1 = 27.5
End Enum
Public Sub Play(myNote As Note, mySeconds As Long, Optional times As Integer = 1)
Dim i As Integer
If times >= 1 Then
For i = 1 To times
Beep myNote, (mySeconds * 300)
Next
End If
End Sub
It creates musical notes...
Then, at the end of your code use something like this:
Sub MusicTest()
Dim Muz As New clsMusic
Muz.Play c4, 1
Muz.Play E4, 1
Muz.Play G4, 1
Muz.Play c5, 3
End Sub
I must mention that I am not the father of the code. I have it in my collection of nice codes. I took it from internet some years before and I do not know who posted it to send the credit in that direction...

Is this correct by ardens lemma?

Just a small question. When applying Ardens lemma(X=RX+S=R*S) on the following..
E3 = 01* + 2E3 I understood it as either one of these but im quite unsure...
E3 = 01*2* or is it E3 = 01* + 2*

How to get values between two inputed data

I have textbox1 and textbox2 which will be the two inputed data, and I want to get the values between them. And the challenge is the ASCW character I and O is not included.
Im using this basis code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim tb1 As String = TextBox1.Text
Dim tb2 As String = TextBox2.Text
Dim cb As String = ""
If tb1.Substring(tb1.Length - 1) <> tb2.Substring(tb2.Length - 1) Then
While (tb1 <> tb2)
Dim temp As String = tb1.Substring(0, tb1.Length - 1)
Dim temp1 As Char = tb1(tb1.Length - 1)
If AscW(UCase(temp1)) >= 48 And AscW(UCase(temp1)) < 90 Then
temp1 = ChrW(AscW(UCase(temp1)) + 1)
ElseIf AscW(UCase(temp1)) >= 90 Then
temp1 = ChrW(AscW(UCase(temp1)) - 42)
End If
tb1 = temp & temp1
If tb1 <> tb2 Then
cb += tb1 & " "
End If
End While
MessageBox.Show(cb)
Else
'Do here
MessageBox.Show("none")
End If
End Sub
Basic arrangement: A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF AG AH AJ AK AL AM AN AP AQ AR AS AT AU AV AW AX AY AZ B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA...... ETC.
The ASCW character I and O is not included.
Example Scenario:
textbox1 = SF446DNLS
textbox2 = SF446DNNZ
Output:
SF446DNLT SF446DNLU SF446DNLV SF446DNLW SF446DNLX SF446DNLY SF446DNLZ SF446DNM0 SF446DNM1 SF446DNM2 SF446DNM3 SF446DNM4 SF446DNM5 SF446DNM6 SF446DNM7 SF446DNM8 SF446DNM9 SF446DNMA SF446DNMB SF446DNMC SF446DNMD SF446DNME SF446DNMF SF446DNMG SF446DNMH SF446DNMJ SF446DNMK SF446DNML SF446DNMM SF446DNMN SF446DNMP SF446DNMQ SF446DNMR SF446DNMS SF446DNMT SF446DNMU SF446DNMV SF446DNMW SF446DNMX SF446DNMY SF446DNMZ SF446DNN0 SF446DNN1 SF446DNN2 SF446DNN3 SF446DNN4 SF446DNN5 SF446DNN6 SF446DNN7 SF446DNN8 SF446DNN9 SF446DNNA SF446DNNB SF446DNNC SF446DNND SF446DNNE SF446DNNF SF446DNNG SF446DNNH SF446DNNJ SF446DNNK SF446DNNL SF446DNNM SF446DNNN SF446DNNP SF446DNNQ SF446DNNR SF446DNNS SF446DNNT SF446DNNU SF446DNNV SF446DNNW SF446DNNX SF446DNNY SF446DNNZ
Check my other answer on Extract data really slow with a 30MB random data file for searching between two strings using Regex:
If you need to exclude I and O, use ^ (based on code in the above answer):
Dim allData = "nonmatch2_strA_match_strB_nonmatch2"
Dim r = Regex.Match(allData, "strA([^IO]*)strB")
You can further fine tune the expression to accept only numbers + characters, but without I and O using
Character Class Subtraction # MSDN

I am trying to run this vba any suggestions

I am rookie in this any suggestions for running it
Private Sub CommandButton1_Click()
Dim LU As Double, HG As String, CN As Double
LU = Range("B1").Value
HG = Range("G1").Value
If HG = A Then
Select Case LU
Case Is = 1
CN = 77
Case Is = 3
CN = 67
Case Is = 4
CN = 30
Case Is = 5
CN = 39
Case Is = 6
CN = 49
Case Is = 7
CN = 77
Case Is = 12
CN = 98
Case Else
CN = 0
End Select
ElseIf HG = B Then
Select Case LU
Case Is = 1
CN = 85
Case Is = 3
CN = 78
Case Is = 4
CN = 55
Case Is = 5
CN = 61
Case Is = 6
CN = 62
Case Is = 7
CN = 86
Case Is = 12
CN = 98
Case Else
CN = 0
End Select
ElseIf HG = C Then
Select Case LU
Case Is = 1
CN = 90
Case Is = 3
CN = 85
Case Is = 4
CN = 70
Case Is = 5
CN = 74
Case Is = 6
CN = 74
Case Is = 7
CN = 91
Case Is = 12
CN = 98
Case Else
CN = 0
End Select
ElseIf HG = D Then
Select Case LU
Case Is = 1
CN = 92
Case Is = 3
CN = 89
Case Is = 4
CN = 77
Case Is = 5
CN = 80
Case Is = 6
CN = 85
Case Is = 7
CN = 94
Case Is = 12
CN = 98
Case Else
CN = 0
End Select
ElseIf HG = NA Then
CN = 98
End If
Range("G1").Value = CN
End Sub
Looking at your variable declarations it appears that you want the code to run based on cell values.
Dim LU As Double, HG As String, CN As Double
LU = Range("B1").Value
HG = Range("G1").Value
If HG = A Then
Select Case LU
I'm guessing that you haven't used the Option Explicit directive at the top of your module so VBA is treating A as a variable instead of a string. I think you want this:
Dim LU As Double, HG As String, CN As Double
LU = Range("B1").Value
HG = Range("G1").Value
If HG = "A" Then
Select Case LU
If that's right then you should probably take care to use Trim$ when you pull the range value (unless you do not want the code to match on A followed by spaces).
You also want to turn on Option Explicit. It will help to trap these types of errors in your code.

Wrong sum calculation of objects in array

I received code with an object (we'll call it Obj) with a property named Number. An array of these objects is defined with 40 objects in indexes 0..39. I don't need object at index 0.
The code has a static variable saving the sum of all Number's of Obj's in the array. This variable is initialized only once. Right after the Number values themselves are defined.
It usually works, but sometimes I log an exception (which I haven't been able to reproduce) with values of different objects and I see there the value of NumberAll is wrong (I've recently logged 1722 and 2134. Not that it should matter - but the only common prime factor for them is 2. should be 1554, if you were wondering, you can check me below :) ).
EDIT: The exception is an Index was outside the bounds of the array on the loop brought in the code below - a direct effect of this issue.
I've tried two methods of summing, brought below.
Relevant code follows. There is nowhere else in the code that a value is assigned to NumberAll.
Static NotFirstTime As Boolean, NumberAll As Integer
If NotFirstTime = False Then GoTo Data
sPoint: 'Code and more code
' ...
' ...
breakValue = someValue Mod NumberAll
Sum = 0
I = 1
Try
Do
If Sum + myArray(I).Number >= breakValue Then
Exit Do
End If
Sum = Sum + myArray(I).Number
I = I + 1
Loop
Catch ex As Exception
'log error and variable data - breakValue is larger than Sum will ever get
'hence the loop reaches the point of trying myArray(40) which doesn't exist
End Try
' ...
Data:
NotFirstTime = True
myArray(1).Number = 37
myArray(2).Number = 34
myArray(3).Number = 44
myArray(4).Number = 31
myArray(5).Number = 59
myArray(6).Number = 26
myArray(7).Number = 33
myArray(8).Number = 28
myArray(9).Number = 20
myArray(10).Number = 13
myArray(11).Number = 92
myArray(12).Number = 65
myArray(13).Number = 71
myArray(14).Number = 22
myArray(15).Number = 22
myArray(16).Number = 42
myArray(17).Number = 26
myArray(18).Number = 26
myArray(19).Number = 33
myArray(20).Number = 34
myArray(21).Number = 22
myArray(22).Number = 19
myArray(23).Number = 85
myArray(24).Number = 72
myArray(25).Number = 47
myArray(26).Number = 40
myArray(27).Number = 47
myArray(28).Number = 54
myArray(29).Number = 48
myArray(30).Number = 44
myArray(31).Number = 37
myArray(32).Number = 34
myArray(33).Number = 44
myArray(34).Number = 9
myArray(35).Number = 57
myArray(36).Number = 37
myArray(37).Number = 19
myArray(38).Number = 13
myArray(39).Number = 68
NumberAll = 0
'Only one of the following methods is used. They seem to give the same result. The bug exists in both.
'Method one
For I = 1 To 39 'E מספר המסכתות
NumberAll = NumberAll + myArray(I).Number
Next I
'Method two
Dim myList As List(Of Obj) = New List(Of Obj)(myArray)
NumberAll = myList.Sum(Function(b) b.Number)
NumberAll -= myArray(0).Number
GoTo sPoint