I have this code below to copy VBA codes from one word document to another (I'm using C#). It works for modules however I can't seem to get it to work with userforms.
VBComponent sourceVBC = GetSourceDocVB();
VBComponent targetVBC = document.VBProject.VBComponents.Add(sourceVBC.Type);
string codes = sourceVBC.CodeModule.get_Lines(1, sourceVBC.CodeModule.CountOfLines);
targetVBC.CodeModule.AddFromString(codes);
targetVBC.Name = sourceVBC.Name;
Yes, the userform is copied to the target document but its fields are not. Like if it contains labels and textboxes. Those fields are not copied. Am I missing something here?
Yes, you are missing something. Forms are not defined in the code file only, but need a binary file too.
You don't tell anything about the way the source files are generated. Normally, in VBA, you use the "Export" statement of the VBComponent object. Of course one can do it manually by going to the VBA Editor in Word, right-clicks the project component and selects "Export". If you have a look into the export folder, you'll see that a form is saved as two files "Form1.frm" (containing the code) and "Form1.frx" (containing binary form data, as labels and other stuff).
In the other project, you can use maually the File, Import function, which takes care of the binary definition if you import a form.
In VBA, you may use something like this to export from a project:
For Each vbC In ActiveDocument.VBProject.VBComponents
Select Case vbC.Type
Case vbext_ct_StdModule
strVbcExt = ".bas"
Case vbext_ct_ClassModule
strVbcExt = ".cls"
Case vbext_ct_MSForm
strVbcExt = ".frm"
Case Else
End Select
strvbCName = vbC.Name
strFilename = strPath & "\" & strvbCName & strVbcExt
vbC.Export strFilename
(omitted the rest)
And to import you'll use
ActiveDocument.VBProject.VBComponents.Import strFilename
Related
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.
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.
I have a table of data (calculation results) that the user should be able to export to different formats. I use Interop.Excel to prepare a table with the data and use the data and format it using visual formatting (fonts, colors etc.) and NumberFormat. Example:
cellRange.NumberFormat = "#,##0";
When I save the table as an Excel file all formatting is ok when exporting to .xlsx and .xls:
excelWorkBook.SaveAs(exportFileName, Excel.XlFileFormat.xlOpenXMLWorkbook); // for .xlsx
excelWorkBook.SaveAs(exportFileName, Excel.XlFileFormat.xlExcel8); // for .xls
I also want to give the user the possibility to export this table to .pdf and .xps from the application without having to open the Excel file. As I have prepared the tables in Interop.Excel, I tried exporting the same table to those file formats:
excelWorkBook.ExportAsFixedFormat(Excel.XlFixedFormatType.xlTypePDF,exportFileName); // for .pdf
excelWorkBook.ExportAsFixedFormat(Excel.XlFixedFormatType.xlTypeXPS,exportFileName); // for .xps
Both of these result in good documents except that all NumberFormats are lost resulting in long decimal values of doubles. This is not appropriate for the customer's summary of the data. (Colors and fonts remain as defined in .pdf and .xps.)
I have tried setting .Styleand .Styles to "Number" or the like. This does not solve the problem.
I have also tried to protect the Range of cells or the excelWorkSheet. This does not solve the problem either.
Someone suggested calling a VBA macro / sub through C# but after some looking into that, I get the impression that it's not a very straight forward (or stable) path.
I am looking for any help in resolving this issue through Interop.Excel or in another way.
lucn
After some testing it seems clear that the property I named in my comment must be set to false:
Microsoft.Office.Interop.Excel.Application.ActiveWindow.DisplayFormulas = false;
It is not evident why this influences the export to other formats such as *.pdfbut this is clearly the case and setting the .DisplayFormulas = false solves the issue.
Hope this helps somebody.
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
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.