Translating "Bodies to Parts" Macro in CATIA V5 from VBA to C# - c#

I'm trying to convert the Bodies from Parts to Parts in a Product in CATIA. I found a VBA script that works fine, but I have to translate it to C#.
The VBA script is the following:
Sub GreateProductsFromBodies_SelectAllBodies()
On Error Resume Next
Set CATIA = GetObject(, "CATIA.Application")
'Declare variables
Dim oPartDoc As PartDocument
Dim oPart As Part
Dim oProductDoc As ProductDocument
Dim oProduct As Product
'Create a new ProductDoc and rename it's PartNumber equals to Partdoc's PartNumber
Set oPartDoc = CATIA.ActiveDocument
Set oProductDoc = CATIA.Documents.Add("Product")
oProductDoc.Product.PartNumber = oPartDoc.Product.PartNumber
'Arrange windows use "Title Vertically" ,then active window contain Partdoc
CATIA.Windows.Arrange catArrangeTiledVertical
CATIA.Windows.Item(1).Activate
'Check the Body's name use "For ... Next"loop . If Body's name duplicate,then rename.
Dim j As Integer, k As Integer
For j = 1 To oPartDoc.Part.Bodies.Count
For k = 1 To oPartDoc.Part.Bodies.Count
If oPartDoc.Part.Bodies.Item(j).name = oPartDoc.Part.Bodies.Item(k).name And j <> k Then
oPartDoc.Part.Bodies.Item(j).name = oPartDoc.Part.Bodies.Item(k).name & "_Rename_" & j
End If
Next
Next
'Copy Bodies from PartDocument
Dim i As Integer, ProductPN As String, FinalProductPN As String
For i = 1 To oPartDoc.Part.Bodies.Count
With oPartDoc.Selection
.Clear
.Add oPartDoc.Part.Bodies.Item(i)
.Copy
.Clear
End With
'Modify the Product's PartNumber,replace "\" and "."to "_" ,then delete Space
ProductPN = oPartDoc.Part.Bodies.Item(i).name
If Right(ProductPN, 1) = "\" Then
ProductPN = Left(ProductPN, Len(ProductPN) - 1)
End If
FinalProductPN = Replace(Replace(Replace(ProductPN, "\", "_"), ".", "_"), " ", "") 'Replace "\" and "."to "_",Delete Space
'Paste Body in Product's Part as Result
Set oProduct = oProductDoc.Product.Products.AddNewComponent("Part", FinalProductPN) 'Add Part
With oProductDoc.Selection
.Clear
.Add oProductDoc.Product.Products.Item(i).ReferenceProduct.Parent.Part
.PasteSpecial "CATPrtResultWithOutLink"
.Clear
End With
oProductDoc.Product.Products.Item(i).ReferenceProduct.Parent.Part.Update
Next
'Use Msgbox to echo the complete flag
MsgBox "All the select Bodies had been created as a PartDocument successfully !" & Chr(13) & _
">>> The Partdocument's Bodies's count : " & oPartDoc.Part.Bodies.Count & Chr(13) & _
">>> The ProductDocument's PartDocument's count : " & oProductDoc.Product.Products.Count, _
vbOKOnly + vbInformation, "#LSY >>> CATIAVBAMacro of Part to Product >>> Run Result"
End Sub
I translated every line, except the line:
oProductDoc.Selection.Add oProductDoc.Product.Products.Item(i).ReferenceProduct.Parent.Part
I found no corresponding property in C#, cause the last property Part is missing in C#.
I wrote:
oProductDoc.Selection.Add(oProductDoc.Product.Products.Item(i).ReferenceProduct.Parent.??????);
I'm very thankfull for every help!

I solved it, if someone else is in this situation:
I had to cast the line as PartDocument, whish gives me the needed .Part Property!
Before the selection:
PartDocument partDoc = oProductDoc.Product.Products.Item(i).ReferenceProduct.Parent as PartDocument;
And in the required line:
oProductDoc.Selection.Add(partDoc.Part);

Related

C# + Excel. NamedRange.Formula

Is there a limit on the length of the formula?
If I use:
string form = "=ЕСЛИ(ЛЕВСИМВ(C2;3)=\"101\";\"цту\";ЕСЛИ(ЛЕВСИМВ(C2;3)=\"102\";\"сзту\";ЕСЛИ(ЛЕВСИМВ(C2;3)=\"103\";\"юту\";ЕСЛИ(ЛЕВСИМВ(C2;3)=\"104\";\"пту\";ЕСЛИ(ЛЕВСИМВ(C2;3)=\"105\";\"уту\";ЕСЛИ(ЛЕВСИМВ(C2;3)=\"106\";\"сту\";ЕСЛИ(ЛЕВСИМВ(C2;3)=\"107\";\"двту\";\"скту\")))))))";
xlWorkSheet.Range["D2"].FormulaLocal = form;
That's all okay.
But if I use:
string form = "=ЕСЛИ(ЛЕВСИМВ(C2;3)=\"101\";\"цту\";ЕСЛИ(ЛЕВСИМВ(C2;3)=\"102\";\"сзту\";ЕСЛИ(ЛЕВСИМВ(C2;3)=\"103\";\"юту\";ЕСЛИ(ЛЕВСИМВ(C2;3)=\"104\";\"пту\";ЕСЛИ(ЛЕВСИМВ(C2;3)=\"105\";\"уту\";ЕСЛИ(ЛЕВСИМВ(C2;3)=\"106\";\"сту\";ЕСЛИ(ЛЕВСИМВ(C2;3)=\"107\";\"двту\";ЕСЛИ(ЛЕВСИМВ(C2;3)=\"108\";\"скту\";\"fuck\"))))))))";
xlWorkSheet.Range["D2"].FormulaLocal = form;
That error takes off:
HRESULT: 0x800A03EC
It seems there is a limit to the length of string written to .FormulaLocal (and other forms of .Formula)
By experimentation in VBA, it apears to be 258 characters. I can find some references on various blogs to this suggesting a limit of about 256, but can find an official source.
Interestingly, this limit doesn't apply if the string doesn't include a = prefix.
Tested on Excel 2010.
For completness, here's the test code
Sub Demo()
Dim s As String, ss As String, f As String
Dim r As Range
Dim i As Long
Set r = [A20]
s = "=""This is a test of string length: "
ss = "z"
On Error GoTo EH
For i = 1 To 350
f = s & ss & """"
Debug.Print ""
Debug.Print Len(f)
r.FormulaLocal = f
Debug.Print "OK"
ss = "z" & ss
Next
Exit Sub
EH:
Debug.Print "Fail"
End Sub
And the last few lines of the result
257
OK
258
OK
259
Fail
It gets weirder: this code works
Sub Demo()
Dim s As String, ss As String, f As String
Dim r As Range
Dim i As Long
Set r = [A20]
s = "IF(A1=1,AAA999,FALSE)"
ss = "z"
r.FormulaLocal = "=" & s
On Error GoTo EH
For i = 1 To 60
Debug.Print ""
Debug.Print Len(r.FormulaLocal)
r.FormulaLocal = Replace(r.FormulaLocal, "AAA999", s)
Debug.Print "OK"
Debug.Print Len(r.FormulaLocal)
Next
Exit Sub
EH:
Debug.Print "Fail"
End Sub
What this does is builds up the formula up in sections, each as a valid Formula in its own right. Fails at about 1000 characters (1024 maybe).
Check the following page for the Excel limits:
https://support.office.com/en-nz/article/Excel-specifications-and-limits-1672b34d-7043-467e-8e27-269d656771c3
In particular, it says:
Length of formula contents - 8,192 characters
Internal length of formula - 16,384 bytes

Copy specific folders to new location

Firs of, i am new here and hope you can help.
I am a systen engeneer and have to move (copy) 400 out of 500 folder's in a directory.
The folder names are uniek GUID {f199a57f-fbee-411b-a70e-32619f87e6aa} naming
Is there a VB or C# way to have the user input the 400 names of the folders that need to be copyd and let the scrip search them and copy the folders too a new location?
Thank you for your help...
Regards,
Wim
Wat i tried:
I tried this, but noting hapens :-(
Sub CopySomeFolder()
Dim FSO, sourceFolder, currentFile, filesInSourceFolder
Dim strSourceFolderPath
Dim strDestinationFolderPath
Dim strUserInput
Set FSO = CreateObject("Scripting.FileSystemObject")
' Figure out which folder to copy from where to where
strUserInput = InputBox("Please enter name of file to copy.")
strSourceFolderPath = "M:\"
strDestinationFolderPath = "M:\"
Set sourceFolder = FSO.GetFolder(strSourceFolderPath)
Set filesInSourceFolder = sourceFolder.Files
' Look at all folders in source folder. If name matches,
' copy to destination folder.
For Each currentFile In filesInSourceFolder
If currentFile.Name = strUserInput Then
currentFile.Copy (FSO.BuildPath(strDestinationFolderPath, _
currentFile.Name))
End If
Next
End Sub
Decide whether you need to copy folders or files
Don't be a sadist - asking a user to type 400 GUIDs into an InputBox!
Use dir to create the list of all 500 folder in a text file
Ask your asistent to delete the 100 not to be copied
Use a .bat or .vbs to copy the 400 remaining folders
This is simple to do. Example script that will read a text file and move them is as fallows;
Const ForReading = 1
Const list = "c:\list_of_folders.txt"
Const destination = "c:\temp\"
Dim fso : Set fso = CreateObject("Scripting.FileSystemObject")
Dim folders : Set folders = fso.OpenTextFile(list, ForReading)
Dim folder
Do Until folders.AtEndOfStream
folder_loc = folders.ReadLine
If fso.FolderExists(folder_loc) Then
Set folder = fso.GetFolder(folder_loc)
folder.move(destination)
End If
Loop
Wscript.echo "Operation completed."
The list_of_folders.txt needs to have full paths.
First of, thank's for all your help...
We ended up using both answers. We got the DB admins to give us the GUIS's that have to be moved, slapt that in too 4 txt doc's, 1 for everyday of the migration. We used copy, not move for if something goes wrong.... here is the script i made...
Dim arrFileLines()
i = 0
set filesys = CreateObject("Scripting.FileSystemObject")
Set objFSO = CreateObject("Scripting.FileSystemObject")
strUserInput = InputBox ("Pathe to TXT file containing the folder names: " & _
chr(10) & chr(10) & "(i.e. C:\Program Files or " & _
"\\Servername\C$\Program Files)")
strUserInputFrom = InputBox("Enter the directory path to the folders u want to copy: " & _
chr(10) & chr(10) & "(i.e. C:\Program Files or " & _
"\\Servername\C$\Program Files)")
strUserInputTo = InputBox("Enter the destination folder: " & _
chr(10) & chr(10) & "(i.e. C:\Program Files or " & _
"\\Servername\C$\Program Files)")
Set objFile = objFSO.OpenTextFile(strUserInput, 1)
Do Until objFile.AtEndOfStream
Redim Preserve arrFileLines(i)
arrFileLines(i) = objFile.ReadLine
i = i + 1
Loop
objFile.Close
For l = Ubound(arrFileLines) to LBound(arrFileLines) Step -1
Wscript.echo strUserInputFrom&"\"&arrFileLines(l) &" copy to " & strUserInputTo&"\"
filesys.CopyFolder strUserInputFrom&"\"&arrFileLines(l), strUserInputTo&"\"
Next
Please let me know if there is a better way, i like to learn :-)
Thanks

Delete Matching Braces in Visual Studio

In Visual Studio I can jump from/to opening/closing brace with the Control+] shortcut.
Is there a shortcut that will allow me to delete both braces at once (maybe with a macro/extension)?
e.g.
foo = ( 1 + bar() + 2 );
When I am on the first opening brace I would like to delete it and its matching brace to get
foo = 1 + bar() + 2;
There isn't an inherent way to do this with Visual Studio. You would need to implement a macro in order for this.
If you choose the macro route you'll want to get familiar with the Edit.GoToBrace command. This is the command which will jump you from the current to the matching brace. Note it will actually dump you after the matching brace so you may need to look backwards one character to find the element to delete.
The best way to implement this as a macro is to
Save the current caret position
Execute Edit.GoToBrace
Delete the brace to the left of the caret
Delete the brace at the original caret position
Make a macro to press Ctrl+] twice and then backspace, then Ctrl+minus and a delete.
The Ctrl+minus moves the cursor back in time.
It's not quite as simple as JaredPar suggested but I'm no Macro expert either.
This works for (), {} and []
Sub DeleteMatchingBrace()
Dim sel As TextSelection = DTE.ActiveDocument.Selection
Dim ap As VirtualPoint = sel.ActivePoint
If (sel.Text() <> "") Then Exit Sub
' reposition
DTE.ExecuteCommand("Edit.GoToBrace") : DTE.ExecuteCommand("Edit.GoToBrace")
If (ap.DisplayColumn <= ap.LineLength) Then sel.CharRight(True)
Dim c As String = sel.Text
Dim isRight As Boolean = False
If (c <> "(" And c <> "[" And c <> "{") Then
sel.CharLeft(True, 1 + IIf(c = "", 0, 1))
c = sel.Text
sel.CharRight()
If (c <> ")" And c <> "]" And c <> "}") Then Exit Sub
isRight = True
End If
Dim line = ap.Line
Dim pos = ap.DisplayColumn
DTE.ExecuteCommand("Edit.GoToBrace")
If (isRight) Then sel.CharRight(True) Else sel.CharLeft(True)
sel.Text = ""
If (isRight And line = ap.Line) Then pos = pos - 1
sel.MoveToDisplayColumn(line, pos)
sel.CharLeft(True)
sel.Text = ""
End Sub
Then add a shortcut to this macro in VS.

How do you jump to a particular row in a DataGridView by typing (a la Windows Explorer details view)

I have a .NET Winforms app in C# with a DataGridView that's read-only and populated with some number of rows. I'd like to have functionality similar to Windows Explorer's (and many other applications) details view for example.
I'd like the DataGridView to behave such that when it has focus if you start typing, the current row selection will jump to the row where the (string) value of cell 0 (i.e. the first column in the row) starts with the characters you typed in.
For example, if I have a DataGridView with 1 column and the following rows:
Bob
Jane
Jason
John
Leroy
Sam
If the DataGridView has focus and I hit the 'b' key on my keyboard, the selected row is now "Bob". If I quickly type in the keys 'ja', the selected row is Jane. If I quickly type in the letters 'jas', the selected row is Jane. If I hit the 'z' key, nothing is selected (since nothing starts with Z).
Likewise if Jane is currently selected and I keep typing the letter 'j', the selection will cycle through to Jason, then John, then back to Jane, each time I hit the 'j' key.
I've been doing some Googling (and "stackoverflowing" :-)) for awhile and cannot find any examples of this type of functionality. I have a rough idea in my head to do this via some sort of short lived timer thread, collecting the keystrokes on KeyPress events for the DataGridView, and selecting rows based on those collected keystrokes matching a Cells[0].Value.StartsWith() type of condition. But it seems like there has to be an easier way that I'm just not seeing.
Any ideas would be much appreciated. Thanks!
I have not seen any built-in functionality like this on DataGridView. I'm pretty sure you'll have to "roll your own".
Are you looking for easier ways to do the "partial search" for the strings?
I wrote a method that will select row letter typed, perhaps you can modify per your needs. The function is called in the KeysPress event handler of the DataGridView.
Method:
'user types letter in dgv, method will select the column starting with that letter if it exists or else next letter existing in dgv
Public Shared Sub GoToLetterTypedInDataGridView(ByVal dgv As DataGridView, ByVal columnName As String, ByVal columnPosition As Integer, ByVal letterTyped As Char)
Try
Dim dt As DataTable = dgv.DataSource
Dim letter As Char = letterTyped
Dim dv As DataView = New DataView(dt)
Dim hasCount As Boolean = False
While (Not hasCount)
dv.Sort = columnName
dv.RowFilter = columnName & " like '" & letter & "%'"
If dv.Count > 0 Then
hasCount = True
Dim x As String = dv(0)(columnPosition).ToString()
Dim bs As New BindingSource
bs.DataSource = dt
dgv.BindingContext(bs).Position = bs.Find(columnName, x)
dgv.CurrentCell = dgv(0, bs.Position)
Else
If letter = "z" Then
letter = "a"
ElseIf letter = "Z" Then
letter = "A"
Else : letter = Chr(Asc(letter) + 1)
End If
End If
End While
Catch ex As Exception
Dim stackframe As New Diagnostics.StackFrame(1)
Throw New Exception("An error occurred in routine, '" & stackframe.GetMethod.ReflectedType.Name & "." & System.Reflection.MethodInfo.GetCurrentMethod.Name & "'." & Environment.NewLine & " Message was: '" & ex.Message & "'")
End Try
End Sub
Then to call:
Private Sub dgvNew_KeyPress(sender As Object, e As System.Windows.Forms.KeyPressEventArgs) Handles dgvNew.KeyPress
Try
If dgvNew.RowCount > 0 Then
GoToLetterTypedInDataGridView(dgvNew, "columnName", 0, e.KeyChar)
End If
Catch ex As Exception
Dim stackframe As New Diagnostics.StackFrame(1)
Throw New Exception("An error occurred in routine, '" & stackframe.GetMethod.ReflectedType.Name & "." & System.Reflection.MethodInfo.GetCurrentMethod.Name & "'." & Environment.NewLine & " Message was: '" & ex.Message & "'")
End Try
End Sub

Outlook/Exchange - how to programmatically export users in distribution list?

How do I export all of the names and email addresses from a distribution list in Outlook using code? I have access to an Outlook 2000 or Outlook 2007 client. Ideally I would like the code to be in C#.
I realize you asked about c#, but the following script from http://www.microsoft.com/technet/scriptcenter/resources/officetips/may05/tips0524.mspx may be of some use.
Const olFolderContacts = 10
Set objOutlook = CreateObject("Outlook.Application")
Set objNamespace = objOutlook.GetNamespace("MAPI")
Set colContacts = objNamespace.GetDefaultFolder(olFolderContacts).Items
intCount = colContacts.Count
For i = 1 To intCount
If TypeName(colContacts.Item(i)) = "DistListItem" Then
Set objDistList = colContacts.Item(i)
Wscript.Echo objDistList.DLName
For j = 1 To objDistList.MemberCount
Wscript.Echo objDistList.GetMember(j).Name & " -- " & _
objDistList.GetMember(j).Address
Next
Wscript.Echo
End If
Next
use outlook component model
http://www.dotnetjunkies.ddj.com/Tutorial/2E1EEEAF-C78A-4A38-A830-AC204B12DF83.dcik

Categories