Copy docx from template and use it as new - c#

I'm using a "template.docx" to copy to my "newDoc.docx" to use some predefined styles or illustrations.
But with this new content, i want to update fields and my table of contents, so it's easy to do it with a vba script, the user don't have to do anything.
But i have a problem, i juste want one execution at the first openning. But if i use the document_new method, my docx is not know as new.
So, how can i "set" it as a new file/doc when i copy it ?
Or maybe i must use a vba variable, modify it when update to prevent for the others updates ?
Thx all !

I generate the doc based on a docx with c# using open xml sdk.
Dim oStory As Range
Dim oField As Field
For Each oStory In ActiveDocument.StoryRanges
For Each oField In oStory.Fields
oField.Update
Next oField
Next oStory
but i wish to execute just one time for the first open.

Related

How to take reports form AVEVA E3D using C#

Is there anybody, who knows how to extract reports from AVEVA E3D using C#?. For example, how to get pipe name, equipment name by using C#.
Is there any document except .NET customization guide, to read about AVEVA E3D and C#?
With AVEVA E3D, you can easily extract them with the command line (using PML - Programmable Macro Langage).
You don't have to use C# but if you really want, you can have a look here :
PDMS C#
Write this into a .txt file :
-- this is a comment
-- Change the path directory, this is your output
!path=|C:\Users\XXX\Desktop\extract.csv|
-- Here you can choose between a lot of type element, like pipe or equi for the sample
-- var !c is a declaration of variable, collect is a collection of type, all equi means every equipment of my MDB (multi database).
var !c collect all equi
-- The first line of my array contains Name, you can delete this if you don't need
!tab = array()
!tab.append('Name')
-- For each values of my array !c which contains all equipment, I do this action
Do !x values !c
-- You can select your attribute, here I choose the name
!name = !x.dbref().name
-- I put the result of the name into my array
!tab.append(!name)
Enddo
!file = object file(!path)
-- I create a object file with the name of my output file, then I choose the Append option and put my array on the output file.
!file.writefile('Append', !tab)
Once you have save this into a .txt file, you have to call it into E3D, open E3D, open the command window and write this : "$m C:\Users\XXX\Desktop\YourMacroName.txt"
The $m call the macro, the syntax is $m PathName\FileName
You can write a macro in .txt format, or like every AVEVA macro, you can choose the .pmlmac format (pml macro). The format doesn't matter, it is just a easy way to recognize the AVEVA macro.

Writing a DataTable from a query to xml

Currently, we generate a shipping manifest file using VBA. I was able to take care of the grunt work of harmonizing, and getting the dataset I need, converted to C#, my last step is to generate the XML file in C# is as well.
The way it works currently, VBA opens a recordset called tblXMLcodes which has 4 fields, Tag, Carrier, Section, and orderct.. Tag has each tag I need, carrier is always the same, section is either Item, or Package as I have two data sets (a package query and an item query) Then the orderct field is just numbered 1-16 for each section.
Then another record set is opened from the item query AND the package query and it gets looped through appending to a .txt file..
How can I easily take my two datasets (both queries) and loop through them to generate an XML file..
Are there any NuGet packages?
Any help is appreciated.. Currently my code works so I wont post it, but if someone wants to see the current I will gladly share. It is VERY slow....
follow this code
DataSet ds = new DataSet();
ds.Tables.Add(dt1); // Table 1
ds.Tables.Add(dt2); // Table 2...
...
string dsXml= ds.GetXml();
...
using (StreamWriter fs = new StreamWriter(xmlFile)) // XML File Path
{
ds.WriteXml(fs);
}

Set a permanent value of a variable without using a database

I don't know how to describe it thoroughly in the title, but I need to set a permanent value of a variable/flag once a process has return true and maybe set some flag in the program itself the value rather than saving it to database. And once that variable/flag has already have that value then the program won't run the process again and just use the value. Is it possible? I'm using VB.Net. I can't use the database because database can be overridden and change values by using query. Thanks in advance!
You can simply use binary/XML serialization in a file to save the state of that variable through your program. Every time you restart your app you can access the value from that file to get its current state.
You can look at this example - http://www.centerspace.net/examples/nmath/csharp/core/binary-serialization-example.php
Basically, you will not save the value in the database but in a file. Anyways you need to persist the value somewhere.
Some ways below
You did not specify if you are afraid that your application or another one could change the value
How I would do it
My ideas below
1)You could use an xml file for example and zip a copy of it with a strong password. Every time you update the first xml you will update also the encrypted zipped xml.You can use a FileSystemWatcher and capture any file change, so if something/someone has changed the file you just get a new copy from the zip
2)You can store the value in the DB and add a trigger to prevent delete/update
for example
-- delete trigger
CREATE TRIGGER Function_Value_Deleted
ON [dbo].[FunctionsValueTb]
AFTER DELETE
AS
BEGIN
SET NOCOUNT ON;
IF EXISTS (
SELECT [Flag] FROM deleted
)
BEGIN
ROLLBACK;
RAISERROR ('Record deletion is not allowed...', 16, 1);
END
END
*You can use also use THROW rather than RAISERROR
**Do the same for the insert and update actions
***You can also store the value into a log table or send an email
I found myself in a situation quite similar to yours a couple of days ago.
In the end, I decided to use the settings functionaly provided by .NET: it is easy to use and maintain, and so far it has given me good results.
Yo can see here what I am talking about:
Best practice to save application settings in a Windows Forms Application
That thread refers to C# but is easily applicable for VB.NET: I just had to follow the same steps in order to add the Settings file:
Right click on the project in Solution Explorer, choose Properties.
Select the Settings tab, click on the hyperlink if settings doesn't
exist. Use the Settings tab to create application settings. Visual
Studio creates the files Settings.settings and
Settings.Designer.settings that contain the singleton class Settings
inherited from ApplicationSettingsBase
And then, from my code, I use the settings like this:
Dim lastExecDate As Date = My.Settings.LastSuccessfulExecution
lastExecDate = lastExecDate.AddDays(1)
// Perform my next execution and do other stuff
My.Settings.LastSuccessfulExecution = lastExecDate
My.Settings.Save()
Next time you retrieve the parameter LastSuccessfulExecution, it will have the updated value.
One more remark, as stated in the post that I linked above:
Note that you need to set the scope property of your settings. If you
select Application scope then Settings.Default.< your property > will
be read-only
Finally, I see that you are using this to store the expiration date of a product, so you don't want the user messing around with it. According to this post, the actual values of the parameters are stored in an Application Data user folder. It is somehow obfuscated since it is not that easy to find and besides it contains a hash on its name... I don't know if that is well hidden enough for you.
If you want the value only to exist in memory when the application is running then you can use the main thread of the application and use:
int slotData = randomGenerator.Next(1, 200);
//to set the data
Thread.SetData(Thread.GetNamedDataSlot("SomeDataKey"), slotData);
//to get the data
int newSlotData = (int)Thread.GetData(Thread.GetNamedDataSlot("SomeDataKey"));
Or you can use the Windows Registry if your app only runs on Windows, if not then you would have to write the value/object to a file and read it from there.

will Excel UDF gets calculation upon open?

My Excel 2007 is set to Auto Calculation Mode.
I have two Excel files. MyUDF (multiple cells) is used in both files.
When I open one file in Excel, I notice no MyUDF is calculated.
But when I open the other file, all MyUDFs are calculated.
So I am a little confused as when will a UDF be calculated upon open and when not?
MyUDF is a UDF in MyAddIn written in C#
Edit
The two files are open in the same instance of Excel. MyUDF is not volatile.
Thanks
Edit
I found http://social.msdn.microsoft.com/Forums/en-US/b477c05a-ae0a-470c-8ad5-482ecd05944b/xll-addin-does-not-calculate-udf-when-opening-a-workbook?forum=exceldev
It says xla will, xll, vba will not.
hmm, this does not match what I see.
Not necessarily. Something like:
Public Function MYUDF() As Date
Application.Volatile
MYUDF = Now
End Function
will be re-calculated, however something like:
Public Function MYUDF() As Date
MYUDF = Now
End Function
may not be re-calculated.
It might be a good idea to set "automatic calculation" in your workbook's Open event. Something like this inside your ThisWorkbook object (this is important!):
Private Sub Workbook_Open()
Application.Calculation = xlCalculationAutomatic
End Sub
This is just to make sure that the setting is set as you expect within your workbook to avoid relying on what calculation mode your Excel application has in its options/settings. If nothing else, at least it eliminates one possibility for why you are getting this behaviour.
Excel "helpfully" remembers where the function was called from.
With he same function in both spreadsheets, Excel may simply be waiting for the other to open so it can do the calculation. Check the formula in the spreadsheet that does not recalculate, and see if it's changed to something like 'C:\MyDocs\MyOtherSpreadsheet.xlsb'!MyUDF(A1).
If it has, search for the full spreadsheet name (including the extra characters it uses for delimiters) and replace with nothing.
If it hasn't, set the calculation to Automatic. To force a recalculation, either select Recalculate now from the ribbon, press F9, or do a search and replace, and replace all the = with exactly the same.

Saving custom settings or attributes in a Word document

I've got a MS Word project where I'm building a number of Panes for users to complete some info which automatically populates text at bookmarks throughout the document. I'm just trying to find the best way of saving these values somehow that I can retrieve them easily when re-opening the document after users have typed in their values.
I could just try to retrieve them from the bookmarks themselves but of course in many cases they contain text values when I'd ideally want to store a primary key somewhere that's not visible to the user and just in case they made changes to the text which would make reverse engineering the values impossible.
I can't seem to find any information on saving custom attributes in a Word document, so would really appreciate some general guidance of how this might be achieved.
Thanks a lot!
I would suggest the use of custom document properties. there you can strings in a key -value manner (at least if it is similar to excel).
I found a thread which explains how to do it:
Set custom document properties with Word interop
After playing around with this a fair bit this is my final code in case it helps someone else, I've found this format easier to understand and work with. It's all based on the referenced article by Christian:
using Office = Microsoft.Office.Core;
using Word = Microsoft.Office.Interop.Word;
using System.Reflection;
Office.DocumentProperties properties = (Office.DocumentProperties)Globals.ThisDocument.CustomDocumentProperties;
//Check if the property exists already
if (properties.Cast<Office.DocumentProperty>().Where(c => c.Name == "nameofproperty").Count() == 0)
{
//Then add the property and value
properties.Add("nameofproperty", false, Office.MsoDocProperties.msoPropertyTypeString, "yourvalue");
}
else
{
//else just update the value
properties["nameofproperty"].Value = "yourvalue";
}
In terms of retrieving the value it's as easy as using the same three lines at the top to get the properties object, perhaps using the code in the if statement to check if it exists, and the retrieving it using properties["nameofproperty"].Value

Categories

Resources