Posts Tagged Value

Email Excel Spreadsheet as Email Body Issues

Hello all. I had a production manager wanting an excel spreadsheet mailed as the body of the email. As some of you know the code generated by excel to produce the email is pretty crazy. But as a result, it showed up fine in Outlook and Android but it did not show the gridlines on the spreadsheet. So this code is based on the excellent work by Ron DeBruin over at http://www.rondebruin.nl/win/s1/outlook/bmail3.htm . I did a replacement for the HTML Range in this manner and the grid lines did appear. And the manager was happy.

Sub Mail_Selection_Range_Outlook_Body()
‘For Tips see: http://www.rondebruin.nl/win/winmail/Outlook/tips.htm
‘Don’t forget to copy the function RangetoHTML in the module.
‘Working in Excel 2000-2016
    Dim rng As Range
    Dim OutApp As Object
    Dim OutMail As Object
‘MsgBox Cells(5, 9).Value
    Set rng = Nothing
    On Error Resume Next
    ‘Only the visible cells in the selection
    Set rng = Selection.SpecialCells(xlCellTypeVisible)
    ‘You can also use a fixed range if you want
    ‘Set rng = Sheets(“YourSheet”).Range(“D4:D12”).SpecialCells(xlCellTypeVisible)
    On Error GoTo 0

    If rng Is Nothing Then
        MsgBox “The selection is not a range or the sheet is protected” & _
               vbNewLine & “please correct and try again.”, vbOKOnly
        Exit Sub
    End If

    With Application
        .EnableEvents = False
        .ScreenUpdating = False
    End With

    Set OutApp = CreateObject(“Outlook.Application”)
    Set OutMail = OutApp.CreateItem(0)

    On Error Resume Next
    With OutMail
        .BodyFormat = olFormatHTML
        .To = “you@you.com”       
           
               
       
         .CC = “”
        .BCC = “”
        .Subject = “Testing Purchase Order Email To Steve”
        .HTMLBody = RangetoHTML(rng)
        Replace .HTMLBody, “border-left:none”, “border-left:solid;border-width: 1px;border-color:black”
        Replace .HTMLBody, “border-right:none”, “border-right:solid;border-width: 1px;border-color:black”
        Replace .HTMLBody, “border-bottom:none”, “border-bottom:solid;border-width: 1px;border-color:black”
        Replace .HTMLBody, “border-top:none”, “border-bottom:solid;border-width: 1px;border-color:black”
        .Send
         ‘or use .Display
    End With
    On Error GoTo 0

    With Application
        .EnableEvents = True
        .ScreenUpdating = True
    End With

    Set OutMail = Nothing
    Set OutApp = Nothing
End Sub

, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,

Leave a comment

WCF and Email Attachments

First off I want to apologize for being away so long. It has been a crazy ride to say the least.

So a colleague of mine ran into an issue with WCF and emailing attachments and asked for help. In this block of code below it would always fail at:

Attachment attachment = new Attachment(fileAttachment.ContentStream, fileAttachment.Name);”     The error is : “Value cannot be null.
Parameter name: stream”

 

 

 
EmailSendInput emailSendInput = new EmailSendInput
                {
                    Attachments = new List<Attachment>(),
                    Body = model.Body,
                    To = new List<string> { model.EmailTo },
                    From = model.EmailFrom,
                    Subject = model.EmailSubject
                };

                if (model.Files != null)
                {
                    foreach (var currAttachment in model.Files)
                    {
                        if (currAttachment != null && currAttachment.ContentLength > 0)
                        {
                            // the filename needs to be nice looking
                            string fileName =
                                currAttachment.FileName.Substring(
                                    currAttachment.FileName.LastIndexOf(@”\”, System.StringComparison.Ordinal) + 1,
                                    currAttachment.FileName.Length
                                    – currAttachment.FileName.LastIndexOf(@”\”, System.StringComparison.Ordinal) – 1);

                            var attachment = new Attachment(currAttachment.InputStream, fileName);
                            emailSendInput.Attachments.Add(attachment);
                        }
                    }
                }

                B2BMortgageDataServiceAgent b2BMortgageDataServiceAgent = new B2BMortgageDataServiceAgent();
                EmailSendResponse emailSendResponse = b2BMortgageDataServiceAgent.SendEmail(emailSendInput);
                if (!emailSendResponse.Success)
                {
                    throw new Exception(emailSendResponse.Message);
                }
            }

public EmailSendResponse SendEmail(EmailSendInput input)
        {
            EmailSendResponse retVal = new EmailSendResponse();
            try
            {
               
                string smtpServer = “”
                string smtpPort = “”

                using (var client = new SmtpClient(smtpServer, Convert.ToInt32(smtpPort)))
                {
                    var mail = new MailMessage
                    {
                        From = new MailAddress(input.From),
                        Subject = input.Subject,
                        Body = input.Body
                    };
                    input.To.ForEach(t => mail.To.Add(t));

                    if (input.Attachments != null && input.Attachments.Count > 0)
                    {
                        foreach (var fileAttachment in input.Attachments)
                        {
                            //Code Crashes here
                            Attachment attachment = new Attachment(fileAttachment.ContentStream, fileAttachment.Name);
                            mail.Attachments.Add(attachment);
                        }
                    }

                    client.Send(mail);
                }

                retVal.Success = true;
            }
            catch (Exception exception)
            {
                retVal.Success = false;
                LogUtil.LogException(exception);

            
                retVal.Message = exception.ToString();
            }

            return retVal;
        }

and then the contract:

[DataContract]
    public class EmailSendInput
    {
        [DataMember]
        public string From { get; set; }

        [DataMember]
        public List<string> To { get; set; }

        [DataMember]
        public string Subject { get; set; }

        [DataMember]
        public string Body { get; set; }

        [DataMember]
        public List<Attachment> Attachments { get; set; }

    }

Implemented as:

public EmailSendResponse SendEmail(EmailSendInput input)
         {
             try
             {
                 return this.dataAgent.SendEmail(input);
             }
             catch (Exception e)
             {
                 this.logger.LogException(e, 2);
                 throw new FaultException(“An error occured in SendEmail. Error details : ” + this.BuildMessage(e));
             } 
         }

and the Email response:

[DataContract]
    public class EmailSendResponse
    {
        [DataMember]
        public bool Success { get; set; }

        [DataMember]
        public string Message { get; set; }
    }

So now we have the problem. I basically had to recreate his datamember for attachment in the contract EmailSendInput to a

public List<EmailEncodedAttachment> Attachments { get; set; }

and added a new contract called EmailEncodedAttachment and process how he was handling the attachment differently. I’ve also included the MVC controller calls in case it might help you as well.

 

SOLUTION:

[DataContract]
    public class EmailSendInput
    {
        [DataMember]
        public string From { get; set; }

        [DataMember]
        public List<string> To { get; set; }

        [DataMember]
        public string Subject { get; set; }

        [DataMember]
        public string Body { get; set; }

        [DataMember]
        public List<EmailEncodedAttachment> Attachments { get; set; }

    }

 

[DataContract]
    public class EmailEncodedAttachment
    {
        [DataMember]
        public string Base64Attachment;

        [DataMember]
        public string Name;

        /// <summary>
        /// One of the System.Net.Mime.MediaTypeNames
        /// </summary>
        [DataMember]
        public string MediaType;
    }
}
                retVal.Message = exception.ToString();
            }

            return retVal;
        }

 

public EmailSendResponse SendEmail(EmailSendInput input)
        {
            EmailSendResponse retVal = new EmailSendResponse();
            try
            {
               
                string smtpServer = ConfigurationManager.AppSettings[“SmtpServer”] ?? “url”;
                string smtpPort = ConfigurationManager.AppSettings[“SmtpPort”] ?? “portnum”;

                using (var client = new SmtpClient(smtpServer, Convert.ToInt32(smtpPort)))
                {
                    var mail = new MailMessage
                    {
                        From = new MailAddress(input.From),
                        Subject = input.Subject,
                        Body = input.Body
                    };
                    input.To.ForEach(t => mail.To.Add(t));

                    if (input.Attachments != null && input.Attachments.Count > 0)
                    {
                        foreach (var fileAttachment in input.Attachments)
                        {
                            mail.Attachments.Add(this.CreateAttachment(fileAttachment));
                        }
                    }

                    client.Send(mail);
                }

                retVal.Success = true;
            }
            catch (Exception exception)
            {
                retVal.Success = false;
                LogUtil.LogException(exception);
             
                retVal.Message = exception.ToString();
            }

            return retVal;
        }

 

The MVC controller action calls the service like so:

EmailSendInput emailSendInput = new EmailSendInput
                {
                    Attachments = new List<EmailEncodedAttachment>(),
                    Body = model.Body,
                    To = new List<string> { model.EmailTo },
                    From = model.EmailFrom,
                    Subject = model.EmailSubject
                };

                if (model.Files != null)
                {
                    foreach (var file in model.Files)
                    {
                        if (file != null && file.ContentLength > 0)
                        {
                            // the filename needs to be nice looking
                            string prettyFileName =
                                file.FileName.Substring(
                                    file.FileName.LastIndexOf(@”\”, System.StringComparison.Ordinal) + 1,
                                    file.FileName.Length
                                    – file.FileName.LastIndexOf(@”\”, System.StringComparison.Ordinal) – 1);

                            var attachment = this.CreateAttachment(prettyFileName, file.InputStream);
                            emailSendInput.Attachments.Add(attachment);
                        }
                    }
                }

                B2BMortgageDataServiceAgent b2BMortgageDataServiceAgent = new B2BMortgageDataServiceAgent();
                EmailSendResponse emailSendResponse = b2BMortgageDataServiceAgent.SendEmail(emailSendInput);
                if (!emailSendResponse.Success)
                {
                    throw new Exception(emailSendResponse.Message);
                }

 

and finally the encoding method which makes this possible:

private EmailEncodedAttachment CreateAttachment(string fileName, Stream stream)
        {
            EmailEncodedAttachment att = new EmailEncodedAttachment
            {
                Name = fileName,
                MediaType = System.Net.Mime.MediaTypeNames.Text.Plain
            };

            byte[] buffer = new byte[stream.Length];
            stream.Read(buffer, 0, (int)stream.Length);
            att.Base64Attachment = Convert.ToBase64String(buffer);

            return att;
        }

 

There you have it folks. I hope you have a great Sunday!

, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,

Leave a comment

Save Control Settings with vb.net

What’s this you say? A new blog entry? If you haven’t completely deserted me …. well I don’t know what’s wrong with you! Smile jk. But anyway here is the latest. I am working for a national hotel chain in Memphis, TN. I got married, moved to New Jersey and am we are now separated. Yes it is a long story and no I am not going to bore you with the details!

Before I go any further, I actually write very little in vb.net anymore. The language is awesome. It’s just that very few people want that skill set now and if you want to be employed you need to write in C#. It’s just the way it is. However in this particular task, I found vb.net to be the tool of choice here. The reason is there is no C# equivalent to VB’s implicit ‘once only’ variable initialization within loops. I am not sure why that is but that is the case here. This code snippet is ideal when you want to allow the end user to dictate how a given control is to look or operate. Yes in my example I am using an Infragistic control so if you copy and paste this do NOT email me complaining about broken references please! I hope you find the code useful and thank you for showing up! Smile

Public Shared Sub SaveControl(ByVal StateName As String, ByVal ParamArray Controls As Control())
        Dim section As String = “”
        Dim appName As String = StringType.FromObject(Interaction.IIf((StringType.StrCmp(Application.ProductName, “”, False) = 0), “VSDesigner”, Application.ProductName))
        Dim control As Control
        For Each control In Controls
            If (Not control.FindForm Is Nothing) Then
                Dim form As Form
                If (StringType.StrCmp((StateName & “”), “”, False) > 0) Then
                    section = String.Concat(New String() { control.FindForm.Name, “.”, control.Name, “.”, StateName })
                Else
                    section = (control.FindForm.Name & “.” & control.Name)
                End If
                If TypeOf control Is Form Then
                    form = DirectCast(control, Form)
                    If (form.WindowState = FormWindowState.Normal) Then
                        Interaction.SaveSetting(appName, form.Name, “Top”, StringType.FromInteger(form.Top))
                        Interaction.SaveSetting(appName, form.Name, “Left”, StringType.FromInteger(form.Left))
                        Interaction.SaveSetting(appName, form.Name, “Height”, StringType.FromInteger(form.Height))
                        Interaction.SaveSetting(appName, form.Name, “Width”, StringType.FromInteger(form.Width))
                    End If
                    Interaction.SaveSetting(appName, form.Name, “WindowState”, StringType.FromInteger(CInt(form.WindowState)))
                ElseIf TypeOf control Is Splitter Then
                    form = control.FindForm
                    Dim splitter As Splitter = DirectCast(control, Splitter)
                    Interaction.SaveSetting(appName, section, “SplitPosition”, StringType.FromInteger(splitter.SplitPosition))
                ElseIf TypeOf control Is FilterListView Then
                    Dim view2 As FilterListView = DirectCast(control, FilterListView)
                    form = view2.FindForm
                    Interaction.SaveSetting(appName, section, “View”, StringType.FromInteger(CInt(view2.ListView.View)))
                    Dim header As ColumnHeader
                    For Each header In view2.ListView.Columns
                        Interaction.SaveSetting(appName, section, (“Column” & StringType.FromInteger(header.Index)), StringType.FromInteger(header.Width))
                    Next
                    Dim filter As FilterListViewFilter
                    For Each filter In view2.Filters
                        Dim tag As UserProfileSetting
                        If (filter.Tag Is Nothing) Then
                            tag = Context.User.Settings.NewItem
                            Dim setting2 As UserProfileSetting = tag
                            setting2.Type = UserProfileSettingTypeEnum.FilterListView
                            setting2.Name = section
                            setting2.Description = filter.Name
                            setting2.Value = filter.Filter
                            setting2 = Nothing
                            filter.Tag = tag
                        ElseIf filter.Deleted Then
                            tag = DirectCast(filter.Tag, UserProfileSetting)
                            If Context.User.Settings.Contains(tag) Then
                                Context.User.Settings.Remove(tag)
                            End If
                        Else
                            tag = DirectCast(filter.Tag, UserProfileSetting)
                            tag.Value = filter.Filter
                        End If
                    Next
                    Context.User.Settings.Save
                ElseIf (TypeOf control Is ListView Or TypeOf control Is SortListView) Then
                    form = control.FindForm
                    Dim view As ListView = DirectCast(control, ListView)
                    Interaction.SaveSetting(appName, section, “View”, StringType.FromInteger(CInt(view.View)))
                    Dim header As ColumnHeader
                    For Each header In view.Columns
                        Interaction.SaveSetting(appName, section, (“Column” & StringType.FromInteger(header.Index)), StringType.FromInteger(header.Width))
                    Next
                ElseIf TypeOf control Is TabControl Then
                    form = control.FindForm
                    Dim control2 As TabControl = DirectCast(control, TabControl)
                    Interaction.SaveSetting(appName, section, “View”, StringType.FromInteger(control2.SelectedIndex))
                ElseIf TypeOf control Is TextBox Then
                    form = control.FindForm
                    Dim box3 As TextBox = DirectCast(control, TextBox)
                    Interaction.SaveSetting(appName, section, “Text”, box3.Text)
                ElseIf TypeOf control Is ComboBox Then
                    form = control.FindForm
                    Dim box As ComboBox = DirectCast(control, ComboBox)
                    If (box.DropDownStyle = ComboBoxStyle.DropDown) Then
                        Interaction.SaveSetting(appName, section, “Text”, box.Text)
                    End If
                    Interaction.SaveSetting(appName, section, “SelectedIndex”, StringType.FromInteger(box.SelectedIndex))
                ElseIf TypeOf control Is CheckBox Then
                    form = control.FindForm
                    Dim box2 As CheckBox = DirectCast(control, CheckBox)
                    Interaction.SaveSetting(appName, section, “Checked”, StringType.FromBoolean(box2.Checked))
                ElseIf TypeOf control Is DataGrid Then
                    form = control.FindForm
                    Dim grid As DataGrid = DirectCast(control, DataGrid)
                    Dim num As Integer = 0
                    Dim style As DataGridTableStyle
                    For Each style In grid.TableStyles
                        Dim num2 As Integer = 0
                        Dim style2 As DataGridColumnStyle
                        For Each style2 In style.GridColumnStyles
                            Interaction.SaveSetting(appName, (section & StringType.FromInteger(num) & “.” & StringType.FromInteger(num2)), “Width”, StringType.FromInteger(style2.Width))
                            num2 += 1
                        Next
                        num += 1
                    Next
                ElseIf TypeOf control Is KeyedDropDown Then
                    form = control.FindForm
                    Dim down As KeyedDropDown = DirectCast(control, KeyedDropDown)
                    If (down.DropDownStyle = ComboBoxStyle.DropDown) Then
                        Interaction.SaveSetting(appName, section, “Text”, down.Text)
                    End If
                    Interaction.SaveSetting(appName, section, “SelectedIndex”, StringType.FromInteger(down.SelectedIndex))
                ElseIf TypeOf control Is UltraGrid Then
                    Dim grid2 As UltraGrid = DirectCast(control, UltraGrid)
                    Dim enumerator2 As BandEnumerator = grid2.DisplayLayout.Bands.GetEnumerator
                    Do While enumerator2.MoveNext
                        Dim current As UltraGridBand = enumerator2.Current
                        Dim enumerator As ColumnEnumerator = current.Columns.GetEnumerator
                        Do While enumerator.MoveNext
                            Dim column As UltraGridColumn = enumerator.Current
                            Interaction.SaveSetting(appName, section, (“Hidden.” & StringType.FromInteger(current.Index) & “.” & column.Key), StringType.FromBoolean(column.Hidden))
                            Interaction.SaveSetting(appName, section, (“Width.” & StringType.FromInteger(current.Index) & “.” & column.Key), StringType.FromInteger(column.Width))
                        Loop
                    Loop
                End If
            End If
        Next
    End Sub

Facebook

, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,

Leave a comment

Write Data From DataTable To Excel With an Array Using C#

This is actually a redo of code written in vb.net a while back that dumps data from a datatable in a dataset into an excel spreadsheet in an effective and fast manner. I am always getting asked how to do this in C# so I decided to put that up today. Yes, I do C# too! Just didn’t want to admit it….

It’s pretty self explanatory. Don’t forget to clean up your excel instance when done. If you have any questions please feel free to send me an email.

Import an excel reference and at the top of your code you need your import statements. Then simply pass your dataset and datatable (granted you could just pass the datatable – I had my reasons for passing the dataset too at the time) to the method. The array is declared as an object because sometimes the compiler has to deal with unforeseen data issues that might arise and it has been effective for me to do let it handle those situations as they arise. I hope you find this useful.

using Excel = Microsoft.Office.Interop.Excel;
using Office = Microsoft.Office.Core;

public void CreateSpreadSheetFromDataSet(DataSet ds, DataTable dt)
        {

            Excel.Application Excel = new Excel.Application();
            Excel.Visible = true;
            Excel.Worksheet WSheet = new Excel.Worksheet();
            Excel.Workbooks.Add();
            WSheet = Excel.ActiveWorkbook.ActiveSheet;
            int rows = ds.Tables[dt.TableName].Rows.Count;
            int columns = ds.Tables[dt.TableName].Columns.Count;
            int r = 0; int c = 0;
            object[,] DataArray = new object[rows + 1, columns + 1];
            for (c = 0; c <= columns – 1; c++)
            {
                DataArray[r, c] = ds.Tables[dt.TableName].Columns[c].ColumnName;
                for (r = 0; r <= rows – 1; r++)
                {
                    DataArray[r, c] = ds.Tables[dt.TableName].Rows[r][c];
                } //end row loop
            } //end column loop

//actually write array to Excel Spreadsheet
            WSheet.Range[“A2”].Resize[rows, columns].Value = DataArray;

            //write header row to spreadsheet
            int DataTableColumnCounter;
            int ExcelColumnCounter = 1; //excel spreadsheets start at 1 when counting columns not zero!
            for (DataTableColumnCounter = 0; DataTableColumnCounter <= ds.Tables[dt.TableName].Columns.Count – 1; DataTableColumnCounter++)
            {
                WSheet.Cells[1, ExcelColumnCounter].Value = ds.Tables[dt.TableName].Columns[DataTableColumnCounter].ColumnName;
                ExcelColumnCounter = ExcelColumnCounter + 1; //moving to next column
            }
        }

My Facebook Link

, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,

1 Comment