• This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Leggi altro.

Aiuto nel creare una macro per Solid Edge

Professione: Studente
Software: Solid Edge ST
Regione: Lombardia
#41
Per finestra immediata intendi la console? Perchè ho fatto tutto come dici ma nella console non vedo nulla. Ci dev'essere qualcosa che mi sfugge...
 
Professione: Studente
Software: Solid Edge ST
Regione: Lombardia
#42
Penso di esser riuscito a risolvere il problema... Ho creato un .txt nel quale vado a scrivere semplicemente in questo modo:
Codice:
Dim ComponentsList As New System.IO.StreamWriter("C:\Users\Guido\Desktop\Tirocinio\Assiemi\Lista.txt")

        For Each Item In objAssembly.Occurrences

            Debug.Print(Item.OccurrenceFileName)
            ComponentsList.Write(Item.OccurrenceFileName)

        Next Item

        ComponentsList.Close()
Ti chiedo ancora un paio di cose però:
- con questo codice ogni volta cerco di creare un nuovo file Lista.txt oppure, se questo esiste già (come succede dalla seconda volta che eseguo la macro in poi) vado semplicemente ad aprirlo ed editarlo?
- se si limita ad aprirlo ed editarlo come faccio prima di editarlo a cancellare il contenuto del file in modo che non rimanga all'interno il contenuto della volta precedente in cui ho eseguito la macro? Questo perchè poi questo file mi servirà per un confronto.
- come faccio ad andare a capo? Al momento ho scritto tutto su una riga.
 

Be_on_edge

Moderatore
Staff Forum
Professione: Progettazione
Software: Solid Edge
Regione: Emilia Romagna
#43
Ti chiedo ancora un paio di cose però:
- con questo codice ogni volta cerco di creare un nuovo file Lista.txt oppure, se questo esiste già (come succede dalla seconda volta che eseguo la macro in poi) vado semplicemente ad aprirlo ed editarlo?
- se si limita ad aprirlo ed editarlo come faccio prima di editarlo a cancellare il contenuto del file in modo che non rimanga all'interno il contenuto della volta precedente in cui ho eseguito la macro? Questo perchè poi questo file mi servirà per un confronto.
- come faccio ad andare a capo? Al momento ho scritto tutto su una riga.
In VB6 quando apri un file di testo devi specificare se vuoi modificarlo o crearlo nuovo. In pratica si aggiunge un "for append" nel caso di editazione. Se non si mette nulla te lo riscrive da zero.

Sempre in VB6 per aggiungere un ritorno a capo io aggiungo "+ VbCrLf" alla fine della riga che scrivo.

Codice:
Open "C:\lista.txt" For Append As #1   'Apertura in modifica
Open "C:\lista.txt" As #1              'Apertura come se fosse nuovo

For Each Item In objAssembly.Occurrences

            Write #1, Item.OccurrenceFileName + VbCrLf

Next Item

Close #1
Ciao
 
Professione: Studente
Software: Solid Edge ST
Regione: Lombardia
#44
Smanettando un pò ero riuscito a fare quel che volevo... a questo punto usando il codice:
Codice:
ComponentsList.Write(Item.OccurrenceFileName)
ogni volta lo apre e lo compila come se fosse nuovo e a me va benissimo così!
Ho un problema con la procedura che mi elenca i componenti dell'assieme: alcuni di questi sono assiemi a sua volta e io ho bisogno di sapere i .par che contengono. Come faccio ad "andare al secondo livello" e quindi elencare i file contenuti in un assieme contenuto in quello principale? Avevo pensato di fare un secondo ciclo for dentro il primo ma mi da un errore che non capisco... il codice era qualcosa di questo tipo:
Codice:
For Each Item In objAssembly.Occurrences

            Debug.Print(Item.OccurrenceFileName)
            VariantComponentsList.WriteLine(Item.OccurrenceFileName)

            For Each SubItem In Item

                Debug.Print(SubItem.Item)
                VariantComponentsList.WriteLine(SubItem.OccurrenceFileName)

            Next SubItem

        Next Item
Una domanda più di logica che di programmazione: se i livelli fossero più di 2 e magari un numero non noto come potrei fare in modo di ottenere una lista che contenga tutti i par? In sostanza dovrei controllare che ogni elemento sia un o meno un assieme e, se è un assieme, fare un ciclo su tutti i suoi componenti; il problema è che poi devo controllare di nuovo se questi sono o meno assiemi e quindi mi sembra sia un circolo vizioso...
 

Leso

Utente Standard
Professione: Ufficiale tecnico
Software: Solid Edge ST9
Regione: Veneto
#45
Dovresti fare un funzione ricorsiva tipo:



Codice:
Sub CercaComponentiAssieme (objAssembly As obj)  'non so se obj o qualcos'altro 

            For Each Item In objAssembly.Occurrences

                  Debug.Print(Item.OccurrenceFileName)
                  VariantComponentsList.WriteLine(Item.OccurrenceFileName)
                  CercaComponentiAssieme (Item)

            Next Item

End Sub
Occio ai codici ricorsivi che stai poco ad andare in loop infinito... :wink:
 
Ultima modifica:

Be_on_edge

Moderatore
Staff Forum
Professione: Progettazione
Software: Solid Edge
Regione: Emilia Romagna
#46
Dovresti fare un funzione ricorsiva tipo:



Codice:
Sub CercaComponentiAssieme (objAssembly As obj)  'non so se obj o qualcos'altro 

            For Each Item In objAssembly.Occurrences

                  Debug.Print(Item.OccurrenceFileName)
                  VariantComponentsList.WriteLine(Item.OccurrenceFileName)
                  CercaComponentiAssieme (Item)

            Next Item

End Sub
Occio ai codici ricorsivi che stai poco ad andare in loop infinito... :wink:

Si esatto la soluzione è questa, si può inserire un controllo per verificare se "Item" è un sottoassieme oppure no ed evitare quindi giri "strani".

A questo punto si può anche inserire un contatore di livello, da scrivere davanti il nome occorrenza in modo da avere la lista con il livello dei pezzi.

Ciao
 
Professione: Studente
Software: Solid Edge ST
Regione: Lombardia
#47
Ho fatto qualcosa del genere:
Codice:
Public Function BOM(ByVal objAssembly As SolidEdgeAssembly.AssemblyDocument) As String

        Dim VariantComponentsList As New System.IO.StreamWriter("C:\Users\Guido\Desktop\Tirocinio\Assiemi\VariantComponentsList.txt")
        Dim VariantComponentName As String = Nothing
        Dim BOMOK As String = "BOM scritta"

        For Each Item In objAssembly.Occurrences
            VariantComponentName = Item.OccurrenceFileName
            VariantComponentsList.WriteLine(Item.OccurrenceFileName)

            If VariantComponentName = "*.asm" Then
                BOM(Item)
            End If

        Next Item

        VariantComponentsList.Close()
        Return BOMOK

    End Function
Il problema è che non funziona... In particolare sembra non verificarsi mai la condizione del ciclo If e quindi la funzione BOM non viene mai richiamata dentro se stessa e così non va mai "al secondo livello". Deduco che il controllo è sbagliato, ma come lo correggo?
Inizialmente ho provato a farlo senza il ciclo If, richiamando direttamente la funzione BOM, ma in questo modo non funziona; penso che sia perchè il primo componente che incontra è un .par mentre in ingresso alla funzione c'è un documento di tipo assembly e quindi credo vada in errore.
 
Professione: Studente
Software: Solid Edge ST
Regione: Lombardia
#48
Sono riuscito a risolvere il problema per cui non si verificava la condizione del ciclo If che controlla se un file è un assieme o meno con un codice di questo tipo:
Codice:
If VariantComponentName.EndsWith(".asm") Then
          BOM(Item)
End If
Ora il controllo funziona però, quando si verifica la condizione VariantComponentName.EndsWith(".asm") e quindi viene richiamata la funzione BOM(), da errore... Qualche idea sul perchè?
 

Be_on_edge

Moderatore
Staff Forum
Professione: Progettazione
Software: Solid Edge
Regione: Emilia Romagna
#49
Sono riuscito a risolvere il problema per cui non si verificava la condizione del ciclo If che controlla se un file è un assieme o meno con un codice di questo tipo:
Codice:
If VariantComponentName.EndsWith(".asm") Then
          BOM(Item)
End If
Ora il controllo funziona però, quando si verifica la condizione VariantComponentName.EndsWith(".asm") e quindi viene richiamata la funzione BOM(), da errore... Qualche idea sul perchè?
Non mi sembra un bel modo di verificare se è un sottoassieme oppure no. Nelle proprietà di item c'è il valore "Type" e devi verificare che sia "Sub-Assembly Object"

Codice:
If Item.Type = igSubAssembly Then ....
Credo anche che sia ora che tu dia un'occhiata alla struttura ad oggetti di solid edge altrimenti rischi tutte le volte di cercare strade improbabili.

Ciao
 
Professione: Studente
Software: Solid Edge ST
Regione: Lombardia
#50
So che non è un metodo ortodosso ma è il più semplice che mi è venuto in mente e per altro funziona. Comunque seguirò il tuo consiglio e approfondirò l'argomento! Il problema però è che, quando tale condizione si verifica, la funzione BOM(item) da errore; nessuna idea a riguardo?
 

Be_on_edge

Moderatore
Staff Forum
Professione: Progettazione
Software: Solid Edge
Regione: Emilia Romagna
#51
So che non è un metodo ortodosso ma è il più semplice che mi è venuto in mente e per altro funziona. Comunque seguirò il tuo consiglio e approfondirò l'argomento! Il problema però è che, quando tale condizione si verifica, la funzione BOM(item) da errore; nessuna idea a riguardo?
Metodo ortodosso che ti porterà ad errori in futuro. Cosa succede se il nome del file è una variante e non finisce con ASM ?

Hai strutturato male la funzione.
Per come è scritta devi assegnargli un risultato stringa.
Nella tua funzione invece non glielo assegni mai.

Anche la riga per chiamare la funzione è sbagliata, ritornando un valore stringa lo devi impiegare in qualche modo (nel tuo caso per scrivere la riga con il risultato).

Ciao
 
Professione: Studente
Software: Solid Edge ST
Regione: Lombardia
#52
Cavoli hai ragione non mi ero accorto dell'errore che generava la ricorsione restituendo una stringa. Ora l'ho corretta utilizzando una funzione di tipo Public Sub che, se non erro, non restituisce alcun valore (la stringa che restituiva era solo di controllo e andava comunque eliminata dopo).
Ciò nonostante però continua a darmi errore... per completezza questo è il nuovo codice della funzione:
Codice:
Public Sub BOM(ByVal objAssembly As SolidEdgeAssembly.AssemblyDocument)

        Dim VariantComponentsList As New System.IO.StreamWriter("C:\Users\Guido\Desktop\Tirocinio\Assiemi\VariantComponentsList.txt")
        Dim VariantComponentName As String = Nothing

        For Each Item In objAssembly.Occurrences
            VariantComponentName = Item.OccurrenceFileName
            VariantComponentsList.WriteLine(Item.OccurrenceFileName)

            If VariantComponentName.EndsWith(".asm") Then
                BOM(Item)
            End If

        Next Item

        VariantComponentsList.Close()

    End Sub
 

Be_on_edge

Moderatore
Staff Forum
Professione: Progettazione
Software: Solid Edge
Regione: Emilia Romagna
#53
Cavoli hai ragione non mi ero accorto dell'errore che generava la ricorsione restituendo una stringa. Ora l'ho corretta utilizzando una funzione di tipo Public Sub che, se non erro, non restituisce alcun valore (la stringa che restituiva era solo di controllo e andava comunque eliminata dopo).
Ciò nonostante però continua a darmi errore... per completezza questo è il nuovo codice della funzione:
Codice:
Public Sub BOM(ByVal objAssembly As SolidEdgeAssembly.AssemblyDocument)

        Dim VariantComponentsList As New System.IO.StreamWriter("C:\Users\Guido\Desktop\Tirocinio\Assiemi\VariantComponentsList.txt")
        Dim VariantComponentName As String = Nothing

        For Each Item In objAssembly.Occurrences
            VariantComponentName = Item.OccurrenceFileName
            VariantComponentsList.WriteLine(Item.OccurrenceFileName)

            If VariantComponentName.EndsWith(".asm") Then
                BOM(Item)
            End If

        Next Item

        VariantComponentsList.Close()

    End Sub
Perchè Item non è un SolidEdgeAssembly.AssemblyDocument ma un SubAssembly.

Ciao
 

Be_on_edge

Moderatore
Staff Forum
Professione: Progettazione
Software: Solid Edge
Regione: Emilia Romagna
#54
Te l'ho scritta così capisci meglio (nel mio esempio stampo un debug, ma puoi inserire la scrittura su file di testo come detto in precedenza).

Codice:
Dim objApp As SolidEdgeFramework.Application
Dim objAsm As SolidEdgeAssembly.AssemblyDocument

Sub Main()

    Set objApp = GetObject(, "SolidEdge.Application")
    Set objAsm = objApp.ActiveDocument
    
    Call BOM(objAsm.Occurrences, "1")

End Sub

Sub BOM(Occurrences As SolidEdgeAssembly.Occurrences, level As String)
    
    For Each Item In Occurrences
    
        If Item.Type = igSubAssembly Then
            Call BOM(Item.OccurrenceDocument.Occurrences, level + 1)
        Else
            Debug.Print level + " - " + Item.OccurrenceFileName
        End If

    Next Item

End Sub
Ciao
 
Professione: Studente
Software: Solid Edge ST
Regione: Lombardia
#55
GRAZIE MILLE!!! Ci ho provato ed ero giunto a qualcosa di simile ma, non ho ancora capito bene perchè, la mia va in loop! Adesso provo con la tua!
 
Professione: Studente
Software: Solid Edge ST
Regione: Lombardia
#56
Ho provato ad adattarla a ciò che serve a me, ma mi da un errore che non capisco; questo è il codice:
Codice:
Public Function BOMOK(ByVal objAssembly As SolidEdgeAssembly.AssemblyDocument) As String

        Dim Message As String = "BOM scritta"

        Call BOM(objAssembly.Occurences, 1)

        Return Message

    End Function

    Public Sub BOM(ByVal Occurrences As SolidEdgeAssembly.Occurrences, ByVal level As String)

        Dim VariantComponentsList As New System.IO.StreamWriter("C:\Users\Guido\Desktop\Tirocinio\Assiemi\VariantComponentsList.txt")

        For Each Item In Occurrences

            If Item.Type = SolidEdgeFramework.ObjectType.igSubAssembly Then
                Call BOM(Item.OccurrenceDocument.Occurrences, level + 1)
            Else
                VariantComponentsList.WriteLine(Item.OccurrenceFileName)
            End If

        Next Item

        VariantComponentsList.Close()

    End Sub
L'errore è in corrispondenza di questa linea:
Codice:
Call BOM(objAssembly.Occurences, 1)
e dice: "Impossibile trovare il membro pubblico 'Occurences' nel tipo 'AssemblyDocument'."
Eppure non mi sembra di aver fatto, almeno in queste linee, qualcosa di diverso da ciò che mi hai suggerito.
Un dettaglio: ho dovuto utilizzare la linea
Codice:
SolidEdgeFramework.ObjectType.igSubAssembly
al posto semplicemente di
Codice:
igSubAssembly
perchè quest'ultima non veniva ricnosciuta. Non penso ci sia differenza comunque no!?
 
Professione: Studente
Software: Solid Edge ST
Regione: Lombardia
#59
Nuova domanda: se io apro 3 istanze di questo tipo
Codice:
Dim VariantComponentsListReader As New System.IO.StreamReader("C:\Users\Guido\Desktop\Tirocinio\Assiemi\VariantComponentsList.txt")
        Dim ParametricComponentsListReader As New System.IO.StreamReader("C:\Users\Guido\Desktop\Tirocinio\Assiemi\ParametricComponentsList.txt")
        Dim ComponentsWithCurveListReader As New System.IO.StreamReader("C:\Users\Guido\Desktop\Tirocinio\Assiemi\ComponentsWithCurveList.txt")
può esserci qualche tipo di problema?
Ho 3 cicli Do While uno dentro l'altro che richiedono la lettura di questi 3 file, ma non funzionano; in particolare, se non ho capito male gli utlimi 2 funzionano correttamente, mentre il primo, quello più esterno, no. Quel che accade è che del primo legge sempre solo la prima riga, ma non capisco perchè non avvenga anche negli altri 2. Questo è il codice della funzione completa:
Codice:
Public Function ConfrontLists() As String

        Dim VariantComponentsListReader As New System.IO.StreamReader("C:\Users\Guido\Desktop\Tirocinio\Assiemi\VariantComponentsList.txt")
        Dim ParametricComponentsListReader As New System.IO.StreamReader("C:\Users\Guido\Desktop\Tirocinio\Assiemi\ParametricComponentsList.txt")
        Dim ComponentsWithCurveListReader As New System.IO.StreamReader("C:\Users\Guido\Desktop\Tirocinio\Assiemi\ComponentsWithCurveList.txt")
        Dim VariantComponentName As String = Nothing
        Dim ParametricComponentName As String = Nothing
        Dim ComponentWithCurveName As String = Nothing
        Dim i As Integer = 0

        Do While VariantComponentsListReader.Peek() <> -1
            VariantComponentName = VariantComponentsListReader.ReadLine()

            Do While ParametricComponentsListReader.Peek() <> -1
                ParametricComponentName = ParametricComponentsListReader.ReadLine()
                i = ParametricComponentName.Length

                If Right(VariantComponentName, i) = ParametricComponentName Then 'VariantComponentName = ParametricComponentName

                    Do While ComponentsWithCurveListReader.Peek() <> -1
                        ComponentWithCurveName = ComponentsWithCurveListReader.ReadLine()

                        If Right(VariantComponentName, i) = ComponentWithCurveName Then
                            Console.WriteLine("Il componente " + VariantComponentName + " contiene una curva")
                            Console.ReadLine()
                        Else
                            Console.WriteLine("Il componente " + VariantComponentName + " non contiene una curva")
                            Console.ReadLine()
                        End If

                    Loop

                End If

            Loop

        Loop

        VariantComponentsListReader.Close()
        ParametricComponentsListReader.Close()
        ComponentsWithCurveListReader.Close()
        Return VariantComponentName

    End Function

End Module
 
Professione: Studente
Software: Solid Edge ST
Regione: Lombardia
#60
Ho scoperto qual'è il problema ma non riesco a risolverlo... Dipende dal metodo peek:
Codice:
ParametricComponentsListReader.Peek() <> -1
A quanto ho capito in questo modo il ciclo procede fino a che non viene restituito il valore -1 dal metodo peek, il che avviene quando il file in questione è stato letto fino all'ultima riga.
Avendo più cicli uno dentro l'altro, una volta che viene restituito -1 in uno di questi cicli questo non viene più eseguito, perchè appunto non si verifica più la condizione d'ingresso nel ciclo.
Dovrei fare in modo che, una volta che viene restituito -1 in un ciclo e si esce da questo, nel ciclo Do While precedente si azzeri il conteggio di questo ciclo (so che è contorto e non si capisce bene, ma è complicato da spiegare); non trovo il codice che serve per far in modo che il valore restituito dal metodo peek non sia più -1, ma ricominci dal valore iniziale. Qualcuno sa il codice che serve per farlo? perchè un altra soluzione sarebbe chiudere il file che si sta leggendo e riaprirlo, ma non mi sembra una soluzione intelligente ed elegante.