I have a simple PDF file that has the Link and the Footnote on a page. When I run the annotation check using iTextSharp, both of the links return the sub type as Link. Is there a way to tell the difference between those two items?
I did examine through an intellisence the structure of an annotation dictionary and notice the annotation object dictionary for the Footnote has once extra item, which is named "F", and that item has a value of 4. That item is NOT present at all in the annotation dictionary for the Link. Can I use the 'F' item/parameter as a way to tell the difference between the Link and the Footnote?
Thank you very much in advance
Here is the PDF file
Here is our code
public string AnyPDFCheckComments(string inFileName, string strUsername, string strFilename)
{
string strCommentType = string.Empty;
string strWidgetFound = string.Empty;
string strPageNumber = string.Empty;
string message = string.Empty;
string strComments = string.Empty;
string strCommentsFound = string.Empty;
int intCommentCount = 0;
PdfReader reader = new PdfReader(inFileName);
for (int i = 1; i <= reader.NumberOfPages; ++i)
{
strPageNumber = i.ToString();
PdfDictionary pagedic = reader.GetPageN(i);
PdfArray annotarray = (PdfArray)PdfReader.GetPdfObject(pagedic.Get(PdfName.ANNOTS));
if (annotarray == null || annotarray.Size == 0)
{
continue;
}
// Finding out the links
foreach (object annot in annotarray.ArrayList)
{
PdfDictionary annotationDic = null;
if (annot is PdfIndirectReference)
{
annotationDic = (PdfDictionary)PdfReader.GetPdfObject((PdfIndirectReference)annot);
}
else
{
annotationDic = (PdfDictionary) annot;
}
PdfName subType = (PdfName)annotationDic.Get(PdfName.SUBTYPE);
if ((subType.Equals(PdfName.TEXT)) && (strCommentsVariables.IndexOf("text") != -1))
{
strCommentType = "text";
//break;
}
else if ((subType.Equals(PdfName.LINK)) && (strCommentsVariables.IndexOf("Link") != -1))
{
strCommentType = "Link";
//break;
}
if ((strCommentType != ""))
{
strCommentsFound = "Yes";
intCommentCount = ++intCommentCount;
strComments = strComments + "<BR>" + "A comment type of '" + "<b>" + strCommentType + "</b>" + "' has been found on page no: " + "<b>" + strPageNumber + "</b>";
if (intCommentCount == 5)
{
break;
}
else
{
strCommentType = string.Empty;
}
}
}
}
return strComments;
}
This code worked for us
var footnoteIdentifier = annotationDic.Get(PdfName.F);
if (footnoteIdentifier != null)
{
continue;
}
I have this code below to generate a report. My problem is why one of the content of my data table can't locate by my code? The ds.dt_ProposedSeminars is the table.
public JsonResult ReportProposal(int year)
{
string Userkey = "gHeOai6bFzWskyUxX2ivq4+pJ7ALwbzwF55dZvy/23BrHAfvDVj7mg ";
string PassKey = "lLAHwegN8zdS7mIZyZZj+EmzlkUXkvEYxLvgAYjuBVtU8sw6wKXy2g ";
JsonResult result = new JsonResult();
MemoryStream oStream;
PCSO_ProposedSeminars rpt = new PCSO_ProposedSeminars();
dsPCSO_TrainingProgram ds = new dsPCSO_TrainingProgram();
//-----------------------------------------------------
var seminars = db.Certificates
.Where(x => x.Year.Value.Year == year && !x.IsApproved.HasValue)
.Select(z => z).Distinct();
foreach (var train in seminars)
{
string trainingProgram = train.CertificateName;
string resourcePerson = train.ResourceSpeaker;
string target = "";
var classifications = db.CertificateTrainingClassifications.Where(a => a.CertificateId == train.CertificateId).Select(b=>b.TrainingClassification.Classification);
int x = 1;
foreach (var classification in classifications)
{
if (classifications.Count() > 1)
{
if (x == 1) target += classification;
else target += ", " + classification;
}
else target += classification;
x++;
}
if (train.TargetParticipants.HasValue)
{
target += "/" + train.TargetParticipants.Value + ((train.TargetParticipants != null) ? " pax" : "");
}
if (train.IsPerBatch.Value)
{
target += "/batch";
}
string duration = train.Duration.Value + " days";
decimal estimatedExpenses = new decimal();
estimatedExpenses = train.EstimatedExpenses.Value;
ds.dt_ProposedSeminars.Adddt_ProposedSeminarsRow(
trainingProgram,
resourcePerson,
target,
duration,
estimatedExpenses);
}
DataTable dtable = new DataTable();
dtable = ds.dt_ProposedSeminars;
rpt.SetDataSource(dtable);
rpt.Refresh();
rpt.SetParameterValue(0, year);
rpt.SetParameterValue(1, "");
rpt.SetParameterValue(2, "Head, Training Unit, Admin Department");
oStream = (MemoryStream)rpt.ExportToStream(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat);
string filename = Convert.ToString((DateTime.Now.Month) + Convert.ToString(DateTime.Now.Day) + Convert.ToString(DateTime.Now.Year) + Convert.ToString(DateTime.Now.Hour) + Convert.ToString(DateTime.Now.Minute) + Convert.ToString(DateTime.Now.Second) + Convert.ToString(DateTime.Now.Millisecond)) + "RequestApplication";
var len = oStream.Length;
FileTransferServiceClient client2 = new FileTransferServiceClient();
RemoteFileInfo rmi = new RemoteFileInfo();
DateTime dt = DateTime.Now;
DownloadRequest dr = new DownloadRequest();
string fId = client2.UploadFileGetId("", filename, len, PassKey, Userkey, oStream);
result.Data = new
{
fileId = fId,
filename = filename
};
rpt.Close();
rpt.Dispose();
oStream.Close();
oStream.Dispose();
result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
return result;
}
Here is the screenshot:
Here is the error.
'PIMS_Reports.TrainingProgram.dsPCSO_TrainingProgram' does not contain a definition for 'dt_ProposedSeminars' and no extension method 'dt_ProposedSeminars' accepting a first arguement of type
'PIMS_Reports.TrainingProgram.dsPCSO_TrainingProgram' could not be found (are you missing a using directive assembly reference?)
The error message states that your dsPCSO_TrainingProgram class does not contain a method or property named dt_PropsedSeminars.
What does that class look like?
What I'm trying to achieve
In my c# application I would like to generate a report (word document) from data in my application, I figured that the best way to do this would be to perform something like a mail merge using the data source from my application.
What I've tried
I tried following this
Mail Merge into word
however this uses GemBox which you need to pay for
I have tried using Microsoft.Office.Interop.Word however I fell
short when I didn't know how to reference the saved template document:
Dictionary<string, string> MailMerge = new Dictionary<string, string>()
{
{ "ID", "123" },
{ "Name", "Test" },
{ "Address1", "Test" },
{ "Address2", "Test" },
{ "Address3", "Test" },
{ "Address4", "Test" },
{ "PostCode", "Test" },
{ "Year End", "Test" },
{ "SicCode", "123" },
};
Document doc = new Document();
doc.MailMerge.Execute(MailMerge);
Summary
I'm looking for some guidance as to what to research further as I believe there must be a 'standard' way of doing this.
Can't believe third party software charge thousands for interface functions with Word. I have perfectly solved this mail merge thing in my project -- no third party, no particular demands on IIS, just use OpenXML.
So, add these 4 functions to your project:
public static void dotx2docx(string sourceFile, string targetFile)
{
MemoryStream documentStream;
using (Stream tplStream = File.OpenRead(sourceFile))
{
documentStream = new MemoryStream((int)tplStream.Length);
CopyStream(tplStream, documentStream);
documentStream.Position = 0L;
}
using (WordprocessingDocument template = WordprocessingDocument.Open(documentStream, true))
{
template.ChangeDocumentType(DocumentFormat.OpenXml.WordprocessingDocumentType.Document);
MainDocumentPart mainPart = template.MainDocumentPart;
mainPart.DocumentSettingsPart.AddExternalRelationship("http://schemas.openxmlformats.org/officeDocument/2006/relationships/attachedTemplate",
new Uri(targetFile, UriKind.Absolute));
mainPart.Document.Save();
}
File.WriteAllBytes(targetFile, documentStream.ToArray());
}
public static void CopyStream(Stream source, Stream target)
{
if (source != null)
{
MemoryStream mstream = source as MemoryStream;
if (mstream != null) mstream.WriteTo(target);
else
{
byte[] buffer = new byte[2048];
int length = buffer.Length, size;
while ((size = source.Read(buffer, 0, length)) != 0)
target.Write(buffer, 0, size);
}
}
}
public static void Mailmerge(string templatePath, string DestinatePath, DataRow dr, DataColumnCollection columns)
{
try
{
dotx2docx(templatePath, DestinatePath);
}
catch //incase the server does not support MS Office Word 2003 / 2007 / 2010
{
File.Copy(templatePath, DestinatePath, true);
}
using (WordprocessingDocument doc = WordprocessingDocument.Open(DestinatePath, true))
{
var allParas = doc.MainDocumentPart.Document.Descendants<DocumentFormat.OpenXml.Wordprocessing.Text>();
Text PreItem = null;
string PreItemConstant = null;
bool FindSingleAnglebrackets = false;
bool breakFlag = false;
List<Text> breakedFiled = new List<Text>();
foreach (Text item in allParas)
{
foreach (DataColumn cl in columns)
{
//<Today>
if (item.Text.Contains("«" + cl.ColumnName + "»") || item.Text.Contains("<" + cl.ColumnName + ">"))
{
item.Text = item.Text.Replace("<" + cl.ColumnName + ">", dr[cl.ColumnName].ToString())
.Replace("«" + cl.ColumnName + "»", dr[cl.ColumnName].ToString());
FindSingleAnglebrackets = false;
breakFlag = false;
breakedFiled.Clear();
}
else if //<Today
(item.Text != null
&& (
(item.Text.Contains("<") && !item.Text.Contains(">"))
|| (item.Text.Contains("«") && !item.Text.Contains("»"))
)
&& (item.Text.Contains(cl.ColumnName))
)
{
FindSingleAnglebrackets = true;
item.Text = global::System.Text.RegularExpressions.Regex.Replace(item.Text, #"\<" + cl.ColumnName + #"(?!\w)", dr[cl.ColumnName].ToString());
item.Text = global::System.Text.RegularExpressions.Regex.Replace(item.Text, #"\«" + cl.ColumnName + #"(?!\w)", dr[cl.ColumnName].ToString());
}
else if //Today> or Today
(
PreItemConstant != null
&& (
(PreItemConstant.Contains("<") && !PreItemConstant.Contains(">"))
|| (PreItemConstant.Contains("«") && !PreItemConstant.Contains("»"))
)
&& (item.Text.Contains(cl.ColumnName))
)
{
if (item.Text.Contains(">") || item.Text.Contains("»"))
{
FindSingleAnglebrackets = false;
breakFlag = false;
breakedFiled.Clear();
}
else
{
FindSingleAnglebrackets = true;
}
if (PreItemConstant == "<" || PreItemConstant == "«")
{
PreItem.Text = "";
}
else
{
PreItem.Text = global::System.Text.RegularExpressions.Regex.Replace(PreItemConstant, #"\<" + cl.ColumnName + #"(?!\w)", dr[cl.ColumnName].ToString());
PreItem.Text = global::System.Text.RegularExpressions.Regex.Replace(PreItemConstant, #"\«" + cl.ColumnName + #"(?!\w)", dr[cl.ColumnName].ToString());
}
if (PreItemConstant.Contains("<") || PreItemConstant.Contains("«")) // pre item is like '[blank]«'
{
PreItem.Text = PreItem.Text.Replace("<", "");
PreItem.Text = PreItem.Text.Replace("«", "");
}
if (item.Text.Contains(cl.ColumnName + ">") || item.Text.Contains(cl.ColumnName + "»"))
{
item.Text = global::System.Text.RegularExpressions.Regex.Replace(item.Text, #"(?<!\w)" + cl.ColumnName + #"\>", dr[cl.ColumnName].ToString());
item.Text = global::System.Text.RegularExpressions.Regex.Replace(item.Text, #"(?<!\w)" + cl.ColumnName + #"\»", dr[cl.ColumnName].ToString());
}
else
{
item.Text = global::System.Text.RegularExpressions.Regex.Replace(item.Text, #"(?<!\w)" + cl.ColumnName + #"(?!\w)", dr[cl.ColumnName].ToString());
}
}
else if (FindSingleAnglebrackets && (item.Text.Contains("»") || item.Text.Contains(">")))
{
item.Text = global::System.Text.RegularExpressions.Regex.Replace(item.Text, #"(?<!\w)" + cl.ColumnName + #"\>", dr[cl.ColumnName].ToString());
item.Text = global::System.Text.RegularExpressions.Regex.Replace(item.Text, #"(?<!\w)" + cl.ColumnName + #"\»", dr[cl.ColumnName].ToString());
item.Text = global::System.Text.RegularExpressions.Regex.Replace(item.Text, #"^\s*\>", "");
item.Text = global::System.Text.RegularExpressions.Regex.Replace(item.Text, #"^\s*\»", "");
FindSingleAnglebrackets = false;
breakFlag = false;
breakedFiled.Clear();
}
else if (item.Text.Contains("<") || item.Text.Contains("«")) // no ColumnName
{
}
} //end of each columns
PreItem = item;
PreItemConstant = item.Text;
if (breakFlag
|| (item.Text.Contains("<") && !item.Text.Contains(">"))
|| (item.Text.Contains("«") && !item.Text.Contains("»"))
)
{
breakFlag = true;
breakedFiled.Add(item);
string combinedfiled = "";
foreach (Text t in breakedFiled)
{
combinedfiled += t.Text;
}
foreach (DataColumn cl in columns)
{
//<Today>
if (combinedfiled.Contains("«" + cl.ColumnName + "»") || combinedfiled.Contains("<" + cl.ColumnName + ">"))
{
//for the first part, remove the last '<' and tailing content
breakedFiled[0].Text = global::System.Text.RegularExpressions.Regex.Replace(breakedFiled[0].Text, #"<\w*$", "");
breakedFiled[0].Text = global::System.Text.RegularExpressions.Regex.Replace(breakedFiled[0].Text, #"<\w*$", "");
//remove middle parts
foreach (Text t in breakedFiled)
{
if (!t.Text.Contains("<") && !t.Text.Contains("«") && !t.Text.Contains(">") && !t.Text.Contains("»"))
{
t.Text = "";
}
}
//for the last part(as current item), remove leading content till the first '>'
item.Text = global::System.Text.RegularExpressions.Regex.Replace(item.Text, #"^\s*\>", dr[cl.ColumnName].ToString());
item.Text = global::System.Text.RegularExpressions.Regex.Replace(item.Text, #"^\s*\»", dr[cl.ColumnName].ToString());
FindSingleAnglebrackets = false;
breakFlag = false;
breakedFiled.Clear();
break;
}
}
}
}//end of each item
#region go through footer
MainDocumentPart mainPart = doc.MainDocumentPart;
foreach (FooterPart footerPart in mainPart.FooterParts)
{
Footer footer = footerPart.Footer;
var allFooterParas = footer.Descendants<Text>();
foreach (Text item in allFooterParas)
{
foreach (DataColumn cl in columns)
{
if (item.Text.Contains("«" + cl.ColumnName + "»") || item.Text.Contains("<" + cl.ColumnName + ">"))
{
item.Text = (string.IsNullOrEmpty(dr[cl.ColumnName].ToString()) ? " " : dr[cl.ColumnName].ToString());
FindSingleAnglebrackets = false;
}
else if (PreItem != null && (PreItem.Text == "<" || PreItem.Text == "«") && (item.Text.Trim() == cl.ColumnName))
{
FindSingleAnglebrackets = true;
PreItem.Text = "";
item.Text = (string.IsNullOrEmpty(dr[cl.ColumnName].ToString()) ? " " : dr[cl.ColumnName].ToString());
}
else if (FindSingleAnglebrackets && (item.Text == "»" || item.Text == ">"))
{
item.Text = "";
FindSingleAnglebrackets = false;
}
}
PreItem = item;
}
}
#endregion
#region replace \v to new Break()
var body = doc.MainDocumentPart.Document.Body;
var paras = body.Elements<Paragraph>();
foreach (var para in paras)
{
foreach (var run in para.Elements<Run>())
{
foreach (var text in run.Elements<Text>())
{
if (text.Text.Contains("MS_Doc_New_Line"))
{
string[] ss = text.Text.Split(new string[] { "MS_Doc_New_Line" }, StringSplitOptions.None);
text.Text = text.Text = "";
int n = 0;
foreach (string s in ss)
{
n++;
run.AppendChild(new Text(s));
if (n != ss.Length)
{
run.AppendChild(new Break());
}
}
}
}
}
}
#endregion
doc.MainDocumentPart.Document.Save();
}
}
public static void MergeDocuments(params string[] filepaths)
{
//filepaths = new[] { "D:\\one.docx", "D:\\two.docx", "D:\\three.docx", "D:\\four.docx", "D:\\five.docx" };
if (filepaths != null && filepaths.Length > 1)
using (WordprocessingDocument myDoc = WordprocessingDocument.Open(#filepaths[0], true))
{
MainDocumentPart mainPart = myDoc.MainDocumentPart;
for (int i = 1; i < filepaths.Length; i++)
{
string altChunkId = "AltChunkId" + i;
AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(
AlternativeFormatImportPartType.WordprocessingML, altChunkId);
using (FileStream fileStream = File.Open(#filepaths[i], FileMode.Open))
{
chunk.FeedData(fileStream);
}
DocumentFormat.OpenXml.Wordprocessing.AltChunk altChunk = new DocumentFormat.OpenXml.Wordprocessing.AltChunk();
altChunk.Id = altChunkId;
//new page, if you like it...
mainPart.Document.Body.AppendChild(new Paragraph(new Run(new Break() { Type = BreakValues.Page })));
//next document
mainPart.Document.Body.InsertAfter(altChunk, mainPart.Document.Body.Elements<Paragraph>().Last());
}
mainPart.Document.Save();
myDoc.Close();
}
}
And use them like this:
DataTable dt = new DataTable();
dt.Columns.Add("Date");
dt.Columns.Add("Today");
dt.Columns.Add("Addr1");
dt.Columns.Add("Addr2");
dt.Columns.Add("PreferContact");
dt.Columns.Add("TenantName");
//......
DataRow nr = dt.NewRow();
nr["Date"] = DateTime.Now.ToString("dd/MM/yyyy");
nr["Today"] = DateTime.Now.ToString("dd/MM/yyyy");
//......
dt.Rows.Add(nr);
string sourceFile = "c:\my_template.docx"; //this is where you store your template
string filePath = "c:\final.docx"; //this is where your result file locate
Mailmerge(sourceFile, filePath, nr, dt.Columns);
Your template(c:\my_template.docx) will be just like normal .docx file, and you need to specify your fields in it:
<field>
So, your template(c:\my_template.docx) should be like:
<Today>
<DebtorName>
<DebtorADDR>
<DebtorEmail>
Dear <Dear>,
Congratulations on yourr property <PlanNo> <BuildAddress>. Your unit number is <LotNo> ...............
In addition, if some of your fields contain line breaks, use this:
nr["Address"] = my_address_text_contains_line_breaks.Replace(Environment.NewLine, "MS_Doc_New_Line");
This is quite simple by using Microsoft.Office.Interop.Word. Here is a simple step by step tutorial on how to do this.
The code to replace a mergefield with a string is like this:
public static void TextToWord(string pWordDoc, string pMergeField, string pValue)
{
Object oMissing = System.Reflection.Missing.Value;
Object oTrue = true;
Object oFalse = false;
Word.Application oWord = new Word.Application();
Word.Document oWordDoc = new Word.Document();
oWord.Visible = true;
Object oTemplatePath = pWordDoc;
oWordDoc = oWord.Documents.Add(ref oTemplatePath, ref oMissing, ref oMissing, ref oMissing);
foreach (Word.Field myMergeField in oWordDoc.Fields)
{
Word.Range rngFieldCode = myMergeField.Code;
String fieldText = rngFieldCode.Text;
if (fieldText.StartsWith(" MERGEFIELD"))
{
Int32 endMerge = fieldText.IndexOf("\\");
Int32 fieldNameLength = fieldText.Length - endMerge;
String fieldName = fieldText.Substring(11, endMerge - 11);
fieldName = fieldName.Trim();
if (fieldName == pMergeField)
{
myMergeField.Select();
oWord.Selection.TypeText(pValue);
}
}
}
}
originally posted here and here
In case you wish to use a dictionary to replace many fields at once use the code below:
public static void TextToWord(string pWordDoc, Dictionary<string, string> pDictionaryMerge)
{
Object oMissing = System.Reflection.Missing.Value;
Object oTrue = true;
Object oFalse = false;
Microsoft.Office.Interop.Word.Application oWord = new Microsoft.Office.Interop.Word.Application();
Microsoft.Office.Interop.Word.Document oWordDoc = new Microsoft.Office.Interop.Word.Document();
oWord.Visible = true;
Object oTemplatePath = pWordDoc;
oWordDoc = oWord.Documents.Add(ref oTemplatePath, ref oMissing, ref oMissing, ref oMissing);
foreach (Microsoft.Office.Interop.Word.Field myMergeField in oWordDoc.Fields)
{
Microsoft.Office.Interop.Word.Range rngFieldCode = myMergeField.Code;
String fieldText = rngFieldCode.Text;
if (fieldText.StartsWith(" MERGEFIELD"))
{
Int32 endMerge = fieldText.IndexOf("\\");
Int32 fieldNameLength = fieldText.Length - endMerge;
String fieldName = fieldText.Substring(11, endMerge - 11);
fieldName = fieldName.Trim();
foreach (var item in pDictionaryMerge)
{
if (fieldName == item.Key)
{
myMergeField.Select();
oWord.Selection.TypeText(item.Value);
}
}
}
}
}
I am also using the same thing but I have more complexity. I have to check the if condition also. In word template file
{ IF «Installment» = Monthly "then the table will appear" "nothing to show" }
when I use the above code shared in the answer. and for if condition in c# I have written
Range rngFieldCode = myMergeField.Code;
String fieldText = rngFieldCode.Text.Trim();
if (fieldText.ToUpper().StartsWith("IF"))
{
myMergeField.UpdateSource();}
so the output is like
{ IF Monthly = Monthly "then table will appear" "nothing to show" }
but the desired output is only "then the table will appear".
when I make 2 parameters. when the cursor on highlight ahref not getting value, as the first parameter? but always get the value of its parent.
What should I do with my code below:
please help correct the errors / shortcomings of my code.
private string LoadNavigasi(string kodeJabatan, ref int countLoop)
{
if (kodeJabatan == null)
kodeJabatan = "001";
DataSet ds = RunQuery("Select KodePosition,NamaPosition,Parent from Position where KodePosition = '" + kodeJabatan + "'");
string temp = string.Empty;
string tempP = string.Empty;
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
var kode = ds.Tables[0].Rows[i][0].ToString();
var nama = ds.Tables[0].Rows[i][1].ToString();
var parent = ds.Tables[0].Rows[i][2].ToString();
if (parent == "")
parent = null;
temp = string.Format("{0}", nama);
tempP = string.Empty;
countLoop++;
if (parent != null)
{
tempP = string.Format("{0}", LoadNavigasi(parent, ref countLoop));
temp = string.Format("{1}<ul><li>{0}", temp, tempP);
}
else
{
temp = string.Format("{0}", temp);
}
return temp;
}
return temp;
}
I'm not sure if it helps but I simplify your code to what it's actually doing.
private string LoadNavigasi(string kodeJabatan)
{
if (kodeJabatan == null)
kodeJabatan = "001";
DataSet ds = RunQuery("Select KodePosition,NamaPosition,Parent from Position where KodePosition = '" + kodeJabatan + "'");
var kode = ds.Tables[0].Rows[0][0].ToString();
var nama = ds.Tables[0].Rows[0][1].ToString();
var parent = ds.Tables[0].Rows[0][2].ToString();
string temp = string.Format("<a href=?Kode={0}&Name={1}>{1}</a>", kode, nama);
if (string.IsNullOrEmpty(parent))
{
string tempP = LoadNavigasi(parent);
temp = string.Format("{1}<ul><li>{0}", temp, tempP);
}
return temp;
}
You mention something about your second parameter in the line
temp = string.Format("{0}", nama);
The second parameter is nama but I don't understand what's wrong with it.
I have method to change cell in datagridView and works fine when i rewrite text (String) .
But I want for example rewrite email to empty value and I dont know how do this. I can only rewrite email to another email (string to another string)
My method to change cell is :
public void ChangeCellEmail(int col, string[] emails)
{
string sep = ";";
string text = "";
foreach (DataGridViewCell cell in dataGridView1.SelectedCells)
{
for (int i = 0; i < emails.Length ;i++)
{
if (emails[i].ToString().Trim() != "")
{
text = text + emails[i] + sep ;
dataGridView1.Rows[cell.RowIndex].Cells[col].Value = text;
}
}
}
}
The calling code of my method is
string mail = txtBox1.Text;
string mail1 = txtBox2.Text;
string mail2 = txtBox3.Text;
string mail3 = txtBox4.Text;
string mail4 = txtBox5.Text;
string[] mails = new string[] { mail, mail1, mail2, mail3, mail4 };
frm1.ChangeCellEmail(2, mails);
this.Dispose();
Thanks for help guys .
Using the following code I can pass in 5 complete email address's of which some / all could be "empty" and the tempVar will always contain the correct data.
public Form1()
{
InitializeComponent();
const string mail = "First";
const string mail1 = "Second";
const string mail2 = "Third";
const string mail3 = "";
const string mail4 = "Fifth";
var mails = new string[] { mail, mail1, mail2, mail3, mail4 };
ChangeCellEmail(2, mails);
}
public void ChangeCellEmail(int col, string[] emails)
{
var sep = ";";
var text = "";
var tempVar = ""; //New temp variable (representing your dataGrid.value)
for (int emailList = 1; emailList < 5; emailList++)
{
for (var i = 0; i < emails.Length; i++)
{
if (emails[i].Trim() != "")
{
text = text + emails[i] + sep;
tempVar = text;
}
else
{
tempVar = string.Empty;
}
}
}
}
Check the tempVar on each loop and you'll see what I am referring to.
Here's a suggested solution:
public void ChangeCellEmail(int emailColumnIndex, string[] emails)
{
var emailsAsCsv = string.Join(";", emails.Where(e => !string.IsNullOrWhiteSpace(e)));
foreach (DataGridViewCell cell in dataGridView1.SelectedCells)
{
dataGridView1.Rows[cell.RowIndex].Cells[emailColumnIndex].Value = emailsAsCsv;
}
}
This updates the selected cells' Email column with the a semi-colon-separated list of non-empty emails.
Usage:
var emailColumnIndex = 2; // The third column in the DataGridView (zero-indexed)
var emails = new[] {txtBox1.Text, txtBox2.Text, txtBox3.Text, txtBox4.Text, txtBox5.Text};
ChangeCellEmail(emailColumnIndex, emails);
Hope this helps.