In my ASP.NET MVC web application, I have used an action to give the user to select the excel file that he wants to upload. Then he submits it and uploaded it to the database.
This works when I run the application from Visual Studio. I have tried in the debug mode.
But when I apply this to the live version, It get an error. User Cannot Upload the excel to the application.
Does any one know the reason why this happens?
This is my controller code
public ActionResult ImportKPIDetails(HttpPostedFileBase excelFile) {
if (excelFile.ContentLength == 0 || excelFile == null) {
ViewBag.Error = "Please select the excel file";
return View("KPIDetails");
} else {
if (excelFile.FileName.EndsWith("xls") || excelFile.FileName.EndsWith("xlsx")) {
string path = Server.MapPath("~/ExcelFile/" + excelFile.FileName);
if (System.IO.File.Exists(path)) System.IO.File.Delete(path);
excelFile.SaveAs(path);
ExcelPath = Server.MapPath("~/ExcelFile/") + path;
Microsoft.Office.Interop.Excel.Application application = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook workbook = application.Workbooks.Open(path);
Microsoft.Office.Interop.Excel.Worksheet worksheet = workbook.ActiveSheet;
Microsoft.Office.Interop.Excel.Range range = worksheet.UsedRange;
List < KPIUploadVM > xcel = new List < KPIUploadVM > ();
for (int i = 2; i <= range.Rows.Count; i++) {
try {
KPIUploadVM kpi = new KPIUploadVM();
int EmpNo = int.Parse(((Microsoft.Office.Interop.Excel.Range) range.Cells[i, 1]).Text);
var EmpId = (from c in db.CreateEmployee where c.EmpNo == EmpNo select c.Id).First();
kpi.EmpId = EmpId;
kpi.KPI = ((Microsoft.Office.Interop.Excel.Range) range.Cells[i, 2]).Text;
kpi.Year = int.Parse(((Microsoft.Office.Interop.Excel.Range) range.Cells[i, 3]).Text);
KPIUploadVM Udata = new KPIUploadVM();
Udata.EmpId = kpi.EmpId;
Udata.KPI = kpi.KPI;
Udata.Year = kpi.Year;
xcel.Add(Udata);
} catch (Exception) {
workbook.Close(true, Missing.Value, Missing.Value);
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(workbook);
application.Quit();
ViewBag.Error = "Error in " + i + " record";
return View("KPIDetails");
}
}
if (xcel != null) {
try {
foreach(var item in xcel) {
int empID = item.EmpId;
string Kpi = item.KPI;
int year = item.Year;
MainKPI e = new MainKPI();
e.EmpId = empID;
e.KPI = Kpi;
e.Year = year;
e.Status = true;
e.CreatedDate = DateTime.Now;
dbs.MainKPI.Add(e);
dbs.SaveChanges();
}
} catch (Exception ex) {
ViewBag.Error = "Error " + ex;
}
TempData["msg"] = "success";
return View("KPIDetails", xcel);
} else {
}
return View("KPIDetails");
} else {
ViewBag.Error = "Selected excel file not supported";
return View("KPIDetails");
}
}
}
Related
I have a method which create an excel file (.xlsx) from a list of strings using DocumentFormat.OpenXml. The created file needs to be repaired when I try to open it with Excel 2016. When I click "Yes" Excel shows my file correctly.
Does anyone have any suggestions? Thanks in advance.
Here's my code:
private byte[] ExportDataXlsx(System.Data.Common.DbDataReader reader, string[] fields, string[] headers, string Culture) {
System.IO.MemoryStream sw = new System.IO.MemoryStream();
using (var workbook = Packaging.SpreadsheetDocument.Create(sw, SpreadsheetDocumentType.Workbook)) {
var sheetData = CreateSheet(workbook);
while (reader.Read()) {
Spreadsheet.Row newRow = new Spreadsheet.Row();
foreach (string column in fields) {
Spreadsheet.Cell cell = new Spreadsheet.Cell();
cell.DataType = Spreadsheet.CellValues.String;
object value = null;
try {
int index = reader.GetOrdinal(column);
cell.DataType = DbKymosDomainService.ToXlsType(reader.GetFieldType(index));
value = DbKymosDomainService.ToStringFromCulture(reader.GetValue(index), reader.GetFieldType(index), Culture);
if (cell.DataType == Spreadsheet.CellValues.Number){
value = value == null ? "" : value.ToString().Replace(",", ".");
}
}
catch { }
cell.CellValue = new Spreadsheet.CellValue(value == null ? null : value.ToString()); //
newRow.AppendChild(cell);
try { var x = newRow.InnerXml; } catch { newRow.RemoveChild(cell); }
}
sheetData.AppendChild(newRow);
}
workbook.Close();
}
byte[] data = sw.ToArray();
sw.Close();
sw.Dispose();
return data;
}
Function which create sheet:
private Spreadsheet.SheetData CreateSheet(Packaging.SpreadsheetDocument workbook)
{
var workbookPart = workbook.AddWorkbookPart();
workbook.WorkbookPart.Workbook = new Spreadsheet.Workbook();
workbook.WorkbookPart.Workbook.Sheets = new Spreadsheet.Sheets();
var sheetPart = workbook.WorkbookPart.AddNewPart<Packaging.WorksheetPart>();
var sheetData = new Spreadsheet.SheetData();
sheetPart.Worksheet = new Spreadsheet.Worksheet(sheetData);
Spreadsheet.Sheets sheets = workbook.WorkbookPart.Workbook.GetFirstChild<Spreadsheet.Sheets>();
string relationshipId = workbook.WorkbookPart.GetIdOfPart(sheetPart);
uint sheetId = 1;
if (sheets.Elements<Spreadsheet.Sheet>().Count() > 0) {
sheetId =
sheets.Elements<Spreadsheet.Sheet>().Select(s => s.SheetId.Value).Max() + 1;
}
Spreadsheet.Sheet sheet = new Spreadsheet.Sheet() { Id = relationshipId, SheetId = sheetId, Name = "Export" };
sheets.Append(sheet);
return sheetData;
}
In my experience when a file needs to be repaired after creating it using OpenXML it means that it is missing a crucial element or the crucial element is in the wrong place. I'm having difficulty following your code so that in itself points to something being in the wrong place. Code should be sequential and self-explanatory. A few pointers however to help with getting to the root cause of your issue.
I would suggest first using ClosedXML as it takes so much strain out of the coding.https://github.com/closedxml/closedxml
Debug your code and step through each step to see what's going on.
Open the created file in OpenXML Productivity Tool https://github.com/OfficeDev/Open-XML-SDK/releases/tag/v2.5 and have a look around.
Another tool that I couldn't be without is OpenXML FileViewer: https://github.com/davecra/OpenXmlFileViewer
Lastly I always run this sub routine to validate documents I create using OpenXML:
public static List<string> ValidateWordDocument(FileInfo filepath, ref Int32 maxerrors = 100)
{
try
{
using (WordprocessingDocument wDoc = WordprocessingDocument.Open(filepath.FullName, false))
{
OpenXmlValidator validator = new OpenXmlValidator();
int count = 0;
List<string> er = new List<string>()
{
string.Format($"Assessment of {filepath.Name} on {DateTime.Now} yielded the following result: {Constants.vbCrLf}")
};
// set at zero so that we can determine the total quantity of errors
validator.MaxNumberOfErrors = 0;
// String.Format("<strong> Warning : </strong>")
foreach (ValidationErrorInfo error in validator.Validate(wDoc))
{
count += 1;
if (count > maxerrors)
break;
er.Add($"Error {count}{Constants.vbCrLf}" + $"Description {error.Description}{Constants.vbCrLf}" + $"ErrorType: {error.ErrorType}{Constants.vbCrLf}" + $"Node {error.Node}{Constants.vbCrLf}" + $"Name {error.Node.LocalName}{Constants.vbCrLf}" + $"Path {error.Path.XPath}{Constants.vbCrLf}" + $"Part: {error.Part.Uri}{Constants.vbCrLf}" + $"-------------------------------------------{Constants.vbCrLf}" + $"Outer XML: {error.Node.OuterXml}" + $"-------------------------------------------{Constants.vbCrLf}");
}
int validatorcount = validator.Validate(wDoc).Count;
switch (validatorcount)
{
case object _ when validatorcount > maxerrors:
{
er.Add($"Returned {count - 1} as this is the Maximum Number set by the system. The actual number of errors in {filepath.Name} is {validatorcount}");
er.Add("A summary list of all error types encountered is given below");
List<string> expectedErrors = validator.Validate(wDoc).Select(_e => _e.Description).Distinct().ToList();
er.AddRange(expectedErrors);
break;
}
case object _ when 1 <= validatorcount && validatorcount <= maxerrors:
{
er.Add($"Returned all {validator} errors in {filepath.Name}");
break;
}
case object _ when validatorcount == 0:
{
er.Add($"No Errors found in document {filepath.Name}");
break;
}
}
return er;
wDoc.Close();
}
}
catch (Exception ex)
{
Information.Err.MessageElevate();
return null;
}
}
It helps greatly with problem solving any potential issues.
I have a custom add-in which gets the body on clicking a button when it got installed. so I am getting this error on a customer machine. code is working fine on my side and for other customers but one customer is facing this problem.
this is my code
private void button1_Click(object sender, RibbonControlEventArgs e)
{
Microsoft.Office.Interop.Outlook.Application olApp = new Microsoft.Office.Interop.Outlook.Application();
Microsoft.Office.Interop.Outlook.NameSpace ns = olApp.GetNamespace("MAPI");
Explorer olExp = olApp.ActiveExplorer();
Selection olSel = olExp.Selection;
string msg = "";
int iterate = 1;
MAPIFolder inbox = null;
if (olSel.Count > 1)
{
MessageBox.Show("Sorry! You can't report more then 1 email at a time", "Report Email");
return;
}
foreach (_MailItem mail in olSel)
{
inbox = ns.GetDefaultFolder(OlDefaultFolders.olFolderInbox);
mail.GetInspector.Display(false);
Thread.Sleep(2100);
string screenShot = getScreenShot(mail);
mail.GetInspector.Close(OlInspectorClose.olDiscard);
String msgToShow = "Are you sure you want to report this email as suspicious?";
if (mail != null && mail.Subject != null)
msgToShow += "\n\nSubject : " + mail.Subject.ToString();
DialogResult dr = MessageBox.Show(msgToShow, "Please Confirm", MessageBoxButtons.YesNo,
MessageBoxIcon.Exclamation);
if (dr == DialogResult.Yes)
{
msg += reportMail(mail, screenShot, e);
}
else {
return;
}
iterate++;
break;
}
if (!msg.Equals(""))
MessageBox.Show(msg, "Report Email");
else
return;
if (!msg.Contains("Success"))
return;
MailItem moveMail = null;
MAPIFolder subfolder = null;
try
{
subfolder = inbox.Folders["Reported Emails"];
}
catch (System.Exception ex) {
subfolder = inbox.Folders.Add("Reported Emails", OlDefaultFolders.olFolderInbox);
}
foreach (MailItem eMail in olSel)
{
try
{
moveMail = eMail;
if (moveMail != null)
{
string titleSubject = (string)moveMail.Subject;
moveMail.Move(subfolder);
}
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
private string reportMail(_MailItem mail, string screenShot, RibbonControlEventArgs e)
{
try
{
var m = Globals.ThisAddIn.Application.GetNamespace("MAPI");
var mailitem = mail;
if (mailitem != null)
{
// Console.WriteLine("Email body ::: " + mailitem.HTMLBody);
String reporterEmail = getReporterEmail(mailitem);
String senderEmailAddress = "";
String senderName = "";
AddressEntry mailsender;
if (reporterEmail.Equals(""))
{
MessageBox.Show("Sorry! This email can't be reported because you are not included in Recipients.", "Report Email");
}
else
{
if (mailitem.SenderEmailType == "EX")
{
mailsender = mailitem.Sender;
if (mailsender != null)
{
if (mailsender.AddressEntryUserType == OlAddressEntryUserType.olExchangeUserAddressEntry || mailsender.AddressEntryUserType == OlAddressEntryUserType.olExchangeRemoteUserAddressEntry)
{
ExchangeUser exchUser = mailsender.GetExchangeUser();
if (exchUser != null)
{
senderEmailAddress = exchUser.PrimarySmtpAddress;
senderName = exchUser.Name;
}
}
}
}
else
{
senderEmailAddress = mailitem.SenderEmailAddress;
senderName = mailitem.SenderName;
}
String emailHeader = mailitem.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x007D001E");
String emailBody = mailitem.Body.Replace("%"," percent").Replace("#","").Replace("|", "");
//String res = HttpPost(Properties.Settings.Default.address, "ReporterEmail=" + reporterEmail + "&suspectedName=" + senderName + "&FromEmail=" + senderEmailAddress
// + "&ToEmail=" + mailitem.To + "&Subject=" + mailitem.Subject + "&EmailBody=" + emailBody + "&AttachmentName=" + GetAttachments(mailitem)
// + "&reporter=" + reporterEmail + "&emailHeader=" + emailHeader + "&mailImage=" + screenShot);
String htmlBody = mail.HTMLBody;
MessageBox.Show(htmlBody);
Dictionary<string, object> postParameters = new Dictionary<string, object>();
postParameters.Add("ReporterEmail", reporterEmail);
postParameters.Add("suspectedName", senderName);
postParameters.Add("FromEmail", senderEmailAddress);
postParameters.Add("ToEmail", mailitem.To);
postParameters.Add("Subject", mailitem.Subject);
postParameters.Add("EmailBody", emailBody);
List<String> attachmentDetails = GetAttachments(mailitem);
postParameters.Add("AttachmentName", attachmentDetails[0]);
postParameters.Add("reporter", reporterEmail);
postParameters.Add("emailHeader", emailHeader);
postParameters.Add("mailImage", screenShot);
string res = HttpPost(Properties.Settings.Default.serverAddress+ "/PhishRod-portlet/reporter", postParameters, htmlBody,attachmentDetails[1]);
return res + "\n";
}
}
}
catch (System.Exception ex)
{
log.Error(ex);
return "Error: " + ex + "-- - " + ex.StackTrace.ToString() + "\n";
}
return "";
}
In the event handler of your button I see the following lines of code:
Microsoft.Office.Interop.Outlook.Application olApp = new Microsoft.Office.Interop.Outlook.Application();
Microsoft.Office.Interop.Outlook.NameSpace ns = olApp.GetNamespace("MAPI");
There is no need to create a new Outlook Application instance in the add-in. Instead, you need to use the Application property which doesn't trigger a security issue when dealing with OOM from external applications:
var app = Globals.ThisAddIn.Application
I am working with a project where I am generating PDF Files from PSR Files. The PDF Files works fine if its a single page but if It has more than two PSR Files and I generate two files it does not open on iPad and works fine on Desktop.
The Third library tool I am using here is 'dbatuotrack' and I am using C#.
Can anyone please guide me how to resolve this problem?
Thanks,
S.
foreach (var pdfform in pdfPagesID)
{
//dbAutoTrack.PDFWriter.Document objDoc = null;
//dbAutoTrack.PDFWriter.Page objPage = null;
objDoc = new dbAutoTrack.PDFWriter.Document();
pdfPagesID.Clear();
pdfPagesID = GetSpecPageID(pdfform);
if (pdfPagesID.Count > 1)
{
foreach (var pdfPage in pdfPagesID)
{
dbAutoTrack.PDFWriter.Page objPage2 = null;
var lastItem = pdfPagesID.Last();
prefixPageID = prefixSpecPageID(pdfPage);
suffixPageIDPSR = prefixPageID + ".psr";
if (File.Exists(PSRPath + suffixPageIDPSR))
{
objDs = new CDatasheet(this.PSRPath + suffixPageIDPSR, false);
objDs.pdfDbHelper = pdfhelper;
//Giving the specformId as SpecFornName
pdfFormName = "Form" + pdfform + ".pdf";
if (!(pdfPage == pdfPagesID.First()))
{
objPage2 = objDs.Generate_PDFReport();
objDoc.Pages.Add(objPage2);
}
else
{
objPage = objDs.Generate_PDFReport();
objDoc.Pages.Add(objPage);
}
if (objPage != null)
{
if (pdfWithNotePage == true && pdfPage.Equals(lastItem))
{
objNotePage = objDs.GetNotePage();
objDoc.Pages.Add(objPage);
objDoc.Pages.Add(objNotePage);
}
else
{
//objDoc.Pages.Add(objPage);
//objDoc.Pages.Add(objPage2);
}
fsOutput = new FileStream(TemplatePath + pdfFormName, FileMode.Create, FileAccess.Write);
objDoc.Generate(fsOutput);
}
if (fsOutput != null)
{
fsOutput.Close();
fsOutput.Dispose();
fsOutput = null;
}
}
}
objDoc = null;
objPage = null;
}
This how I tweaked the code to make it work. Thanks for the suggestion DJ KRAZE
foreach (var pdfform in pdfPagesID)
{
//dbAutoTrack.PDFWriter.Document objDoc = null;
//dbAutoTrack.PDFWriter.Page objPage = null;
objDoc = new dbAutoTrack.PDFWriter.Document();
pdfPagesID.Clear();
pdfPagesID = GetSpecPageID(pdfform);
if (pdfPagesID.Count > 1)
{
foreach (var pdfPage in pdfPagesID)
{
dbAutoTrack.PDFWriter.Page objPage2 = null;
var lastItem = pdfPagesID.Last();
prefixPageID = prefixSpecPageID(pdfPage);
suffixPageIDPSR = prefixPageID + ".psr";
if (File.Exists(PSRPath + suffixPageIDPSR))
{
objDs = new CDatasheet(this.PSRPath + suffixPageIDPSR, false);
objDs.pdfDbHelper = pdfhelper;
//Giving the specformId as SpecFornName
pdfFormName = "Form" + pdfform + ".pdf";
if (!(pdfPage == pdfPagesID.First()))
{
objPage2 = objDs.Generate_PDFReport();
objDoc.Pages.Add(objPage2);
}
else
{
objPage = objDs.Generate_PDFReport();
objDoc.Pages.Add(objPage);
}
if (objPage != null)
{
if (pdfWithNotePage == true && pdfPage.Equals(lastItem))
{
objNotePage = objDs.GetNotePage();
objDoc.Pages.Add(objPage);
objDoc.Pages.Add(objNotePage);
}
else
{
//objDoc.Pages.Add(objPage);
//objDoc.Pages.Add(objPage2);
}
}
}
}
fsOutput = new FileStream(TemplatePath + pdfFormName, FileMode.Create, FileAccess.Write);
objDoc.Generate(fsOutput);
//This region was the problem, disposing the output everytime.
//Needed it to be included after completion of iteration
if (fsOutput != null)
{
fsOutput.Close();
fsOutput.Dispose();
fsOutput = null;
}
}
I am trying to pass value from C# code to a CrystalReport report.
Edit
private void PrintOrder(List<OrderPrintBO> pListOrderBO)
{
DSOrderReport oDSOrderReport = new DSOrderReport();
DataTable oDataTable = oDSOrderReport.Tables[0];
String sOrderNo = "";
if (pListOrderBO.Count > 0)
{
for (int i = 0; i < pListOrderBO.Count; i++)
{
DataRow oRow = oDataTable.NewRow();
oRow["OrderID"] = pListOrderBO[i].OrderID;
oRow["OrderNumber"] = pListOrderBO[i].OrderNumber;
sOrderNo = pListOrderBO[i].OrderNumber;
oDataTable.Rows.Add(oRow);
}
}
oDSOrderReport.Merge(oDataTable);
oDSOrderReport.AcceptChanges();
if (oDSOrderReport.Tables[0].Rows.Count > 0)
{
// Main Copy
PrintDialog printDialog = new PrintDialog();
rptOrder oMainOrder = new rptOrder();
String sCompanyName = System.Configuration.ConfigurationManager.AppSettings["CompanyName"].ToString();
String sPhone1 = System.Configuration.ConfigurationManager.AppSettings["Phone1"].ToString();
String sPhone2 = System.Configuration.ConfigurationManager.AppSettings["Phone2"].ToString();
String sShowOrderNo = System.Configuration.ConfigurationManager.AppSettings["ShowOrderNo"].ToString();
((CrystalDecisions.CrystalReports.Engine.TextObject)oMainOrder.ReportDefinition.ReportObjects["txtCompanyName"]).Text = sCompanyName;
((CrystalDecisions.CrystalReports.Engine.TextObject)oMainOrder.ReportDefinition.ReportObjects["txtPhone1"]).Text = "Tel:" + sPhone1;
((CrystalDecisions.CrystalReports.Engine.TextObject)oMainOrder.ReportDefinition.ReportObjects["txtPhone2"]).Text = "Tel:" + sPhone2;
////This commented out section gives exception
//string sVarOrderNo = "";
//if (sShowOrderNo.ToLower() == "yes")
//{
// sVarOrderNo = sOrderNo;
//}
//((CrystalDecisions.CrystalReports.Engine.TextObject)oMainOrder.ReportDefinition.ReportObjects["txtOrderNo"]).Text = "O.N. : " + sVarOrderNo;
oMainOrder.SetDataSource(oDSOrderReport);
oMainOrder.PrintOptions.PrinterName = printDialog.PrinterSettings.PrinterName;
try
{
oMainOrder.PrintToPrinter(1, false, 0, 0);
MessageBox.Show("Order Printed Successfully", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
}
else
{
MessageBox.Show("Error in Printing Order", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
End Edit
For the first three text boxes (CompanyName, Phone1 & Phone2), every thing working just fine, but when I tried to pass the OrderNo to the report, Index was outside the bounds of the array. exception is occured, even though my report have a TextBox object named txtOrderNo
I am not sure why this is happening. Please help. Thanks.
Try to change your sOrderNo related code is as below.
string sVarOrderNo = "";
if (sShowOrderNo.ToLower() == "yes")
{
sVarOrderNo = sOrderNo;
}
((CrystalDecisions.CrystalReports.Engine.TextObject)oMainOrder.ReportDefinition.ReportObjects["txtOrderNo"]).Text = "O.N. : " + sVarOrderNo;
UPDATE
Your problem is below mentioned code snippet.Inside the for loop you try to assign a value to sOrderNo. Which is meaningless.B'cos it overrides every time when loop goes.So what is the purpose of this ? If you need this value then you have to bring this value through as your table's row or as a parameter to the report.
if (pListOrderBO.Count > 0)
{
for (int i = 0; i < pListOrderBO.Count; i++)
{
DataRow oRow = oDataTable.NewRow();
oRow["OrderID"] = pListOrderBO[i].OrderID;
oRow["OrderNumber"] = pListOrderBO[i].OrderNumber;
sOrderNo = pListOrderBO[i].OrderNumber;
oDataTable.Rows.Add(oRow);
}
}
I hope this will help to you.
We have a WinForm application that uses VSTO to generate an Excel file from a Template.
Occasionally (frequently) the file opens (because you can use the cursor keys and the formula and cell changes) but it is invisible. Even if you save the file and open it back up, it is still invisible.
The users use Excel 2007 and pretty much all (6 - 8) of our users experience this problem.
The (temporary) fix I have given them is to choose "Arrange All". When this is done, the worksheet pops into view.
I have seen several causes and fixes for this on the web. Everything from using a graphic in the template that was in Excel 2003, but isn't in Excel 2007.
The template is pretty "simple". It has formulas, fonts and colors and that is about it.
The template (and WinForm application) is deployed to the users via Click Once.
Here is the code from the "ThisWorkbook.cs" file:
public string TemplateTableName;
public string TemplateSelectStatement;
private void ThisWorkbook_Startup(object sender, System.EventArgs e)
{
Properties.Settings.Default.myConnectionString = Registry.GetValue("myConnectionString", Properties.Settings.Default.appConnectionString).ToString();
TemplateTableName = Registry.GetValue("TemplateTableName", string.Empty).ToString();
TemplateSelectStatement = Registry.GetValue("TemplateSelectStatement", string.Empty).ToString();
AppLog.ConnectionString = Properties.Settings.Default.myConnectionString;
}
Here is the code from the "Sheet1.cs" file:
private const int StartingDataRow = 4;
private int LastRow;
private int NextAvailableColumn = 18;
DataSet myDS = new DataSet();
Dictionary<string, object[,]> xlsColumnData = new Dictionary<string, object[,]>();
private void Sheet1_Startup(object sender, System.EventArgs e)
{
try
{
if (Globals.ThisWorkbook.TemplateTableName == string.Empty) throw new Exception("TemplateTableName is not set in the registry.");
if (Globals.ThisWorkbook.TemplateSelectStatement == string.Empty) throw new Exception("TemplateSelectStatement is not set in the registry.");
Application.ScreenUpdating = false;
if (Globals.ThisWorkbook.TemplateTableName.Length > 31)
this.Name = Globals.ThisWorkbook.TemplateTableName.Substring(0, 31);
else
this.Name = Globals.ThisWorkbook.TemplateTableName;
LoadTableData();
LoadDataArrays();
BindDataToColumns();
ApplyFormulas();
ApplyFormatting();
this.Range["B4", missing].Select();
Application.ScreenUpdating = true;
AppLog.WriteEvent(DateTime.Now, Environment.UserName, Environment.MachineName, Globals.ThisWorkbook.TemplateTableName, TraceEventType.Information, "Creating customer list");
Globals.ThisWorkbook.RemoveCustomization();
}
catch (Exception ex)
{
AppLog.Show(ex.Message, "Sheet1_Startup", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, TraceEventType.Error);
}
finally
{
Application.ScreenUpdating = true;
}
}
private void LoadTableData()
{
try
{
Application.Cursor = XlMousePointer.xlWait;
string selectCommandText = Globals.ThisWorkbook.TemplateSelectStatement.Replace("[Bind_Type]", "dbo.GetBindingCodeDescription([Bind_Type]) AS Binding_Description");
SqlDataAdapter da = new SqlDataAdapter(selectCommandText, Public_No_Holdings.Properties.Settings.Default.myConnectionString);
da.SelectCommand.CommandTimeout = 60;
if (da.SelectCommand.Connection.State != ConnectionState.Closed) da.SelectCommand.Connection.Close();
da.Fill(this.myDS);
LastRow = (StartingDataRow + this.myDS.Tables[0].Rows.Count) - 1;
}
catch (Exception ex)
{
AppLog.Show(ex.Message, "Loading Table", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
Application.Cursor = XlMousePointer.xlDefault;
}
}
private void LoadDataArrays()
{
System.Data.DataTable dt = this.myDS.Tables[0];
// insert the data into the object[,]
object[,] rowData;
dt.Columns["Imprint"].ColumnName = "Publisher"; //Alias the Imprint dataset column to populate the "Publisher" xls column
for (int iCol = 0; iCol < dt.Columns.Count; iCol++)
{
rowData = new object[dt.Rows.Count, 1];
for (int iRow = 0; iRow < dt.Rows.Count; iRow++)
{
switch (dt.Columns[iCol].ColumnName)
{
case "EAN":
rowData[iRow, 0] = "'" + dt.Rows[iRow][iCol];
break;
case "IPage_Link":
rowData[iRow, 0] = String.Format("=HYPERLINK(\"{0}\", \"{1}\")", dt.Rows[iRow][iCol], "iPage");
break;
default:
rowData[iRow, 0] = dt.Rows[iRow][iCol];
break;
}
}
xlsColumnData.Add(dt.Columns[iCol].ColumnName, rowData);
}
}
private void BindDataToColumns()
{
NamedRange nr;
Range rng;
foreach (KeyValuePair<string, object[,]> kvp in xlsColumnData)
{
try
{
if (this.Controls.Contains(kvp.Key))
{
nr = (NamedRange)this.Controls[kvp.Key];
// Reduce range (remove header rows)
rng = this.Range[this.Cells[StartingDataRow, nr.Column], this.Cells[LastRow, nr.Column]];
rng.Value2 = kvp.Value;
}
else
{
this.Cells[StartingDataRow - 1, NextAvailableColumn].Value2 = kvp.Key;
rng = this.Range[this.Cells[StartingDataRow, NextAvailableColumn], this.Cells[LastRow, NextAvailableColumn]];
rng.Value2 = kvp.Value;
NextAvailableColumn++;
}
}
catch (Exception ex)
{
AppLog.Show(ex.Message, "BindDataToColumns - " + kvp.Key, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void ApplyFormulas()
{
Range rng;
int iCol;
// Book Invoice
iCol = this.BookInvoice.Column;
rng = this.Range[this.Cells[StartingDataRow, iCol], this.Cells[LastRow, iCol]];
rng.Select();
rng.FillDown();
// Your Cost
iCol = this.YourCost.Column;
rng = this.Range[this.Cells[StartingDataRow, iCol], this.Cells[LastRow, iCol]];
rng.Select();
rng.FillDown();
}
private void ApplyFormatting()
{
// For some reason Hyperlink columns get reset
this.IPage_Link.Font.Name = this.EAN.Font.Name;
this.IPage_Link.Font.Size = this.EAN.Font.Size;
((Range)this.Cells[StartingDataRow, 1]).EntireRow.Select();
Application.ActiveWindow.FreezePanes = true;
}