Spire.Doc is a professional Word .NET library specifically designed for developers to create, read, write, convert and print Word document files. Get free and professional technical support for Spire.Doc for .NET, Java, Android, C++, Python.

Thu May 27, 2021 1:53 pm

Hello,
i have a Problem to get a Field from Text, how cames from the Database.
For Example (here is an example text who has an { DOCVARIABLE TEST } but Spire Doc doesn't discover as a Field.
How can I solve this Problem? Only fields how definied in the .docx would be discovered.
Best Regards.

Yerodin84
 
Posts: 13
Joined: Thu May 27, 2021 1:39 pm

Fri May 28, 2021 11:30 am

Hello,

Thanks for your inquiry.

Sorry I’m not very clear about your requirements. Could you please provide your test code and a sample .docx document with the Field you mentioned to help us has a better understanding? Thanks in advance for your assistance.
Sincerely,
Andy
E-iceblue support team
User avatar

Andy.Zhou
 
Posts: 483
Joined: Mon Mar 29, 2021 3:03 am

Fri May 28, 2021 12:11 pm

That's the Problem.
The Document is creating by design time. I Try to explain it as good as well.
My Document have an Section Break. After this Section Break i Load a List of Text Modlues dynamically from the Database and Insert this. Now in one of the Textmodule the text was for Example
"Hello Mister { DOCVARIABLE "NAME" //*MERGEOPTION } ....." So when I Load this Text Module from the Database and insert this Text have I no problems.
But i need a real Variable in the Document and not only the text.

var selections = doc.FindAllPattern(docVarPattern);
foreach ( var selection in selections )
{
var name = ExtractName(docVarNamePattern.Match(selection.SelectedText).Value);
var range = selection.GetAsOneRange();
var field = range.OwnerParagraph.AppendField(name, FieldType.FieldDocVariable);
field.Code = " DOCVARIABLE "+name;


var index = range.OwnerParagraph.ChildObjects.IndexOf(range);
range.OwnerParagraph.ChildObjects.Insert(index,field);
}

when i Debug, i get the value an the Field is in the Fieldscollection, but wenn I saved this document to xps, i get an instance = null exception, but I could not find out where the Error comes from.
I hope it's more understandable now.

Yerodin84
 
Posts: 13
Joined: Thu May 27, 2021 1:39 pm

Mon May 31, 2021 11:23 am

Hello,

Thanks for your response and sorry for late reply on weekend.

Please refer to the modified code below.
Code: Select all
            //A temp section to store the added fields
            Section tempSection = doc.AddSection();
            var selections = doc.FindAllPattern(docVarPattern);
            foreach (var selection in selections)
            {
               
                var name = ExtractName(docVarNamePattern.Match(selection.SelectedText).Value);
                Paragraph tem = tempSection.AddParagraph();
                var range = selection.GetAsOneRange();
                var index = range.OwnerParagraph.ChildObjects.IndexOf(range);

                Field field1 = tem.AppendField(name, FieldType.FieldDocVariable);
                field1.Code = "DOCVARIABLE \"" + name+"\"";
                //Copy the field items into the target paragraph
                foreach (DocumentObject obj in tem.ChildObjects)
                {
                    range.OwnerParagraph.ChildObjects.Insert(index++, obj.Clone());
                }

            }
            //Remove the temp section
            doc.Sections.Remove(tempSection);
            //Save to file
            doc.SaveToFile("output.xps", FileFormat.XPS);
            doc.SaveToFile("output.docx", FileFormat.Docx);


If you have any other questions, please feel free to contact us.
Sincerely,
Andy
E-iceblue support team
User avatar

Andy.Zhou
 
Posts: 483
Joined: Mon Mar 29, 2021 3:03 am

Mon May 31, 2021 12:58 pm

Yeah cool, that's nearly correct, but now I have in the Fieldcollection duplicates and the placeholder (find out with the Regex) doesn't remove and i can't update the field with a Variable. Could You help me please??
thanks :)

Yerodin84
 
Posts: 13
Joined: Thu May 27, 2021 1:39 pm

Tue Jun 01, 2021 8:29 am

Yerodin84 wrote:Yeah cool, that's nearly correct, but now I have in the Fieldcollection duplicates and the placeholder (find out with the Regex) doesn't remove and i can't update the field with a Variable. Could You help me please??
thanks :)


Hello,

Thanks for your response.
I did notice that there are duplicate fields in the FieldCollection , and it will cause an exception if I add the line “doc.IsUpdateFields = true” to update the fields.
To avoid this issue and remove the placeholder you mentioned, please refer to the following modified code.

Code: Select all
                       Document doc = new Document("Test.docx");
            doc.IsUpdateFields = true;
            //A temp document to avoid the fieldcollection duplicates
            Document doc2 = new Document();
            var section = doc2.AddSection();
            var selections = doc.FindAllPattern(docVarPattern);
            foreach (var selection in selections)
            {
                var par = section.AddParagraph();
                var name = ExtractName(docVarNamePattern.Match(selection.SelectedText).Value);
                var range = selection.GetAsOneRange();
                var index = range.OwnerParagraph.ChildObjects.IndexOf(range);
                Field field1 = par.AppendField(name, FieldType.FieldDocVariable);
                field1.Code = "DOCVARIABLE " + name;

                //Copy the field items into the target paragraph
                foreach (DocumentObject obj in par.ChildObjects)
                {
                    range.OwnerParagraph.ChildObjects.Insert(index++, obj.Clone());
                }
                //Remove the orginal text
                range.OwnerParagraph.ChildObjects.Remove(range);
            }
            doc.IsUpdateFields = true;
            //Save to file
            doc.SaveToFile("output.xps", FileFormat.XPS);
            doc.SaveToFile("output.docx", FileFormat.Docx);
            doc.Dispose();
            doc2.Dispose();

If there is any question, just feel free to contact us.
Sincerely,
Andy
E-iceblue support team
User avatar

Andy.Zhou
 
Posts: 483
Joined: Mon Mar 29, 2021 3:03 am

Tue Jun 01, 2021 12:46 pm

As soon I use range.OwnerParagraph.ChildObjects.Remove(range); there is an exception with the object reference. I think, when i use Remove the whole Property was removed. Is it a Bug?

Yerodin84
 
Posts: 13
Joined: Thu May 27, 2021 1:39 pm

Wed Jun 02, 2021 7:35 am

Hi,

Thanks for your response.
After many tests, the code runs without any exceptions on my side. Your issue may be related to your test file.
To help us better reproduce your issue and help you solve it, could you please provide your input document and complete test code for our reference? You can upload the document and code here, or send them to us via email (support@e-iceblue.com). Thanks in advance.
Sincerely,
Andy
E-iceblue support team
User avatar

Andy.Zhou
 
Posts: 483
Joined: Mon Mar 29, 2021 3:03 am

Wed Jun 02, 2021 8:47 am

Thank you,
it was really my problem, because I given't the document to the next Procedure and so it was an old object.

But now i can't fill the Field with a Value (i.e. doc.Variables.Add("TITEL1","TEST") dosn't work.... The output is always "TITEL1";

Yerodin84
 
Posts: 13
Joined: Thu May 27, 2021 1:39 pm

Wed Jun 02, 2021 10:40 am

Yerodin84 wrote:Thank you,
it was really my problem, because I given't the document to the next Procedure and so it was an old object.

But now i can't fill the Field with a Value (i.e. doc.Variables.Add("TITEL1","TEST") dosn't work.... The output is always "TITEL1";


Thank you for your reply.

Are you using VBA to update the fields? If so, to help us further investigate the issue, could you please provide your VBA code and the docx document? Thanks in advance.
Sincerely,
Andy
E-iceblue support team
User avatar

Andy.Zhou
 
Posts: 483
Joined: Mon Mar 29, 2021 3:03 am

Fri Jun 04, 2021 8:25 am

Hey,
no I use C#.
Here my Code

// Thats my Main Methode
private void CreateBagDokument()
{
// BAG Vorlage
var file = SelectedVorlage.Pfad;
var bag = new Document();
//BAG Vorlage wird gelesen
bag.LoadFromFile(file);

bag = AddList(bag);
// Lade die Parameter
var param = new BagParameter();
param = LoadParameter(@"C:\temp\BAG.json");
bag = SetInhalt(bag, param);
bag = ReplaceFields(bag, param);
//Sektion des Tenors
// bag.SaveToFile(@"C:\temp\testfile.rtf", FileFormat.Rtf);
//DocContent = File.ReadAllText(@"C:\temp\testfile.rtf");

bag.SaveToFile(@"C:\temp\" + Path.GetFileNameWithoutExtension(SelectedVorlage.Pfad) + ".xps",
FileFormat.XPS);
var xpsDocument =
new XpsDocument(@"C:\temp\" + Path.GetFileNameWithoutExtension(SelectedVorlage.Pfad) + ".xps",
FileAccess.Read);
Dokument = xpsDocument.GetFixedDocumentSequence();
xpsDocument.Close();
}


private Document AddList( Document dok )
{

var tenorStyle = new ListStyle(dok, ListType.Numbered) { Name = "tenorstyle" };
tenorStyle.Levels[0].PatternType = ListPatternType.Arabic;
tenorStyle.Levels[1].NumberPrefix = "\x0000.";
dok.ListStyles.Add(tenorStyle);
var tenorSection = dok.Sections[0];
var grundSection = dok.Sections[1];
var rechtSection = dok.Sections[2];
var tenorList = new List<Textbausteine>();
var grundList = new List<Textbausteine>();
var rechtList = new List<Textbausteine>();

if ( BausteineList != null )
{
foreach ( var item in BausteineList )
{

if ( item.IsSelected )
{
switch ( item.Briefbereich )
{
case 0:
tenorList.Add(item);
break;
case 1:
grundList.Add(item);
break;
case 2:
rechtList.Add(item);
break;

}
}
}

// Tenor
foreach ( var item in tenorList )
{
//var str = Regex.Matches(item.Inhalt, docVarPattern);
//foreach ( Match name in str )
//{

// var nm = Regex.Match(name.Value, docVarNamePattern);
//}

var paragraph = tenorSection.AddParagraph();
paragraph.AppendText(item.Inhalt);
paragraph.ApplyStyle(BuiltinStyle.BodyText1I);
paragraph.ListFormat.ApplyStyle("tenorstyle");
paragraph.AppendBreak(BreakType.LineBreak);
}

// Gründe
foreach ( var item in grundList )
{
var paragraph = grundSection.AddParagraph();
paragraph.AppendText(item.Inhalt);
paragraph.AppendBreak(BreakType.LineBreak);
}

// Rechtsbehelfsbelehrung
foreach ( var item in rechtList )
{
var paragraph = rechtSection.AddParagraph();
paragraph.AppendText(item.Inhalt);
paragraph.AppendBreak(BreakType.LineBreak);
}

}

return dok;
}

protected BagParameter LoadParameter( string file )
{
var openStream = File.ReadAllText(file, Encoding.GetEncoding("iso-8859-1"));
if ( !string.IsNullOrEmpty(openStream) )
{
try
{
var par = JsonSerializer.Deserialize<BagParameter>(openStream);
return par;
}
catch ( Exception e )
{
var _manager = new NotificationManager();
var content = new NotificationContent
{

Title = "Error",
Message = "Die Übernahme der Daten hat nicht funktioniert!\n" + e.Message,
Type = NotificationType.Error
};

_manager.ShowAsync(content, expirationTime: TimeSpan.FromSeconds(10));
return null;
}
}
return null;
}

private Document ReplaceFields( Document doc, BagParameter param )
{
if ( doc == null )
{
var doknew = new Document();
return doknew;
}



doc.Variables.Add("BEZIRK", param.Bezirk ?? "");
doc.Variables.Add("BEZIRKADRESSE", param.Bezirkadresse ?? "");
doc.Variables.Add("SITZUNGSDATUM", param.SitzungDatum.ToShortDateString() + " ");
doc.Variables.Add("DOKID", param.DokId ?? "");
doc.Variables.Add("KUERZEL", Regex.Match(param.Sachbearbeiter, @"\(.*\)").ToString() ?? "");
var orderedEnumerable = param.BeisitzerArzt.OrderBy(x => x.Vorsitz).ThenBy(x => x.Name);
var count = 1;
foreach ( var arzt in orderedEnumerable )
{
doc.Variables.Add("BEISITZERARZT" + count, arzt.Vorname + " " + arzt.Name + " ");
count++;
}

var kk = param.BeisitzerKK.FirstOrDefault(x => x.Vorsitz);
doc.Variables.Add("BEISITZERKK1", kk?.Vorname + " " + kk?.Name + " ");
foreach ( var bekk in param.BeisitzerKK )
{
if ( bekk != kk && doc.Variables["BEISITZERKK2"] == null )
{
doc.Variables.Add("BEISITZERKK2", bekk.Vorname + " " + bekk.Name + " ");
kk = bekk;
}
if ( bekk != kk && doc.Variables["BEISITZERKK3"] == null )
{
doc.Variables.Add("BEISITZERKK3", bekk.Vorname + " " + bekk.Name + " ");
kk = bekk;
}
if ( bekk != kk && doc.Variables["BEISITZERKK4"] == null )
{
doc.Variables.Add("BEISITZERKK4", bekk.Vorname + " " + bekk.Name + " ");
kk = bekk;
}
}

doc.Variables.Add("TITEL1", "Doktore");
doc.IsUpdateFields = true;
return doc;
}

private Document SetInhalt( Document doc, BagParameter param )
{
const string Pattern = @"\{+(\s?)+(.*?)+(\s?)+\}";
const string Patter = @"""[^""]*""";
var docVarPattern = new Regex(Pattern);
var docVarNamePattern = new Regex(Patter);


//A temp document to avoid the fieldcollection duplicates
var doc2 = new Document();
var section = doc2.AddSection();
var selections = doc.FindAllPattern(docVarPattern);
foreach ( var selection in selections )
{
var par = section.AddParagraph();
var name = ExtractName(docVarNamePattern.Match(selection.SelectedText).Value);
var range = selection.GetAsOneRange();
var index = range.OwnerParagraph.ChildObjects.IndexOf(range);
var field1 = par.AppendField(name, FieldType.FieldDocVariable);
field1.Code = " DOCVARIABLE " + name + " ";

//Copy the field items into the target paragraph
foreach ( DocumentObject obj in par.ChildObjects )
{
range.OwnerParagraph.ChildObjects.Insert(index++, obj.Clone());
}
//Remove the orginal text
range.OwnerParagraph.ChildObjects.Remove(range);
}


return doc;

}

private string ExtractName( string fieldCode )

{

const string pattern = @"DOCVARIABLE\\s+(?<name>[^\\s\""]+)|(\""(?<name>[^\""]+)\"").*";

var match = Regex.Match(fieldCode, pattern);

return match.Result("${name}");

}

Yerodin84
 
Posts: 13
Joined: Thu May 27, 2021 1:39 pm

Fri Jun 04, 2021 12:27 pm

Thank you for sharing.
Since I can't run the code you provided directly, I made the some modifications to your code and then tested it with the latest version of Spire.Doc v9.6.0, but found that the value of the variable can be updated normally. Below is my test code.
Code: Select all
        static void Main(string[] args)
        {
            CreateBagDokument();
        }
        public static void CreateBagDokument()
        {
            var bag = new Document();
            bag.LoadFromFile("Test.docx");
            bag = SetInhalt(bag);
            bag = ReplaceFields(bag);
            bag.SaveToFile("test.xps", Spire.Doc.FileFormat.XPS);
            bag.SaveToFile("test2.docx", Spire.Doc.FileFormat.Docx);
        }

        public static Document ReplaceFields(Document doc)
        {
            doc.Variables.Add("Name1", "BEZIRK222");
            doc.Variables.Add("Name2", "Doktore");
            doc.Variables["Name3"] = "TEST";
            doc.IsUpdateFields = true;
            return doc;
        }
        public static Document SetInhalt(Document doc)
        {
            var doc2 = new Document();
            var section = doc2.AddSection();
            var selections = doc.FindAllString("Document",false,true);
            int i = 1;
            foreach (var selection in selections)
            {
                var par = section.AddParagraph();
                var name = "Name" + i;
                i++;
                var range = selection.GetAsOneRange();
                var index = range.OwnerParagraph.ChildObjects.IndexOf(range);
                var field1 = par.AppendField(name, FieldType.FieldDocVariable);
                field1.Code = " DOCVARIABLE " + name + " ";
                //Copy the field items into the target paragraph
                foreach (DocumentObject obj in par.ChildObjects)
                {
                    range.OwnerParagraph.ChildObjects.Insert(index++, obj.Clone());
                }
                //Remove the orginal text
                range.OwnerParagraph.ChildObjects.Remove(range);
            }
            return doc;
        }
    }

If you are not using the latest version, please download it and test again. If the issue still exists, please provide your full test project for further investigation. Thank you in advance.
Sincerely,
Andy
E-iceblue support team
User avatar

Andy.Zhou
 
Posts: 483
Joined: Mon Mar 29, 2021 3:03 am

Sun Jun 06, 2021 1:15 pm

Hello,
thank you very much,
i Ithink the error is in my ExtractName Method. Perhaps I have invisible signs (ANSI --> UTF8) in this and so the Name of the Field couldn't located.
With you example,All Fields are resolved.

I had the version 9.4. .... now I have updatet.

Best regards
Dirk

Yerodin84
 
Posts: 13
Joined: Thu May 27, 2021 1:39 pm

Mon Jun 07, 2021 11:41 am

Thanks for your feedback.

According your description, I simulated a Word file with the text “Hello Mister { DOCVARIABLE "NAME" //*MERGEOPTION }” and then tested it with the methods (SetInhalt and ExtractName) you provided, I indeed found that the field cannot be updated correctly. This issue has been logged in our bug tracking system with the ticket SPIREDOC-6124. If there is any update, we will let you know. Apologize for the inconvenience caused.
Sincerely,
Andy
E-iceblue support team
User avatar

Andy.Zhou
 
Posts: 483
Joined: Mon Mar 29, 2021 3:03 am

Thu Jun 17, 2021 5:46 am

Hello,

Thanks for your patience!
Regarding the issue SPIREDOC-6124, you can refer to the following modified code to test it.
Code: Select all
        private static Document SetInhalt(Document doc)
        {
            const string Pattern = @"\{+(\s?)+(.*?)+(\s?)+\}";
            const string Patter = @"""[^""]*""";
            var docVarPattern = new Regex(Pattern);
            var docVarNamePattern = new Regex(Patter);

            var selections = doc.FindAllPattern(docVarPattern);
            foreach (var selection in selections)
            {
                var name = ExtractName(docVarNamePattern.Match(selection.SelectedText).Value);
                var range = selection.GetAsOneRange();
                var index = range.OwnerParagraph.ChildObjects.IndexOf(range);
                Field field = new Field(doc);
                field.Type = FieldType.FieldAdvance;
                field.Code = " DOCVARIABLE " + name + " ";
                range.OwnerParagraph.ChildObjects.Insert(index++, field);
                FieldMark fm = new FieldMark(doc, FieldMarkType.FieldSeparator);
                range.OwnerParagraph.ChildObjects.Insert(index++,fm);
                FieldMark endFM = new FieldMark(doc, FieldMarkType.FieldEnd);
                field.End = endFM;
                range.OwnerParagraph.ChildObjects.Insert(index++, endFM);
                range.OwnerParagraph.ChildObjects.Remove(range);
            }
            return doc;
        }

If you have any other question, please feel free to contact us.
Sincerely,
Andy
E-iceblue support team
User avatar

Andy.Zhou
 
Posts: 483
Joined: Mon Mar 29, 2021 3:03 am

Return to Spire.Doc