I am trying to use a TEXT File to read in data into femap, but I am having some difficulty in getting the code right.
Below I have the code and attatched the .txt file.
Sub Main Dim App As femap.model Set App = feFemap() Dim readFile As femap.Read Set readFile = App.feRead Dim s As femap.Surface Set s = App.feSurface Dim colorSet1 As femap.Set, colorSet2 As femap.Set Set colorSet1 = App.feSet Set colorSet2 = App.feSet Dim sSet As femap.Set, gr As femap.Group Set sSet = App.feSet Dim thickness As Variant Set gr = App.feGroup Dim t As String rc = App.feFileGetName( "Select File with FemapColorID", "Text Files", ".txt", True, t) If rc = FE_OK Then rc = readFile.Open(t, 80) If rc = FE_OK Then While Not readFile.AtEOF rc = readFile.Read gr.ID = readFile.RealField (1,0) colorSet2.ID = readFile.IntField (2, 0) thickness = readFile.IntField (3,0) Wend End If End If While s.Next If colorSet1.IsAdded(s.color) = FE_FAIL Then colorSet1.Add(s.color) colorSet2.Add(s.ID) End If Wend While colorSet2.Next sSet.Clear sSet.AddRule(colorSet2.CurrentID,FGD_SURFACE_BYCOLOR) gr.SetAdd(FT_SURFACE,sSet.ID) s.Get(colorSet2.CurrentID) gr.title = "Plate = " & thickness gr.Put(gr.ID) Wend End Sub
Basically I want to bring in a model into femap whereby the model is different colors based on its thickness. So I would like femap to read in the text file and then create groups based on the color of the surfaces.
Thanking you in advance
A few tips & questions:
1) add the star in the getfilename method: "*.txt"
2) is there a specific reason for the group IDs to appear? Or is it enough if the macro creates a group without over writing any already existing group? if the later you can delete the "groupID" column and use gr.put(gr.NextEmptyID).
This is a general comment: FEMAP is very good in dealing with IDs. Unless you have a precise reason for forcing IDs, leave this consideration to FEMAP.
3) now the tricky, convoluted part: from what I understand you want a corrspondance between color and thickness (indicated in group title). This can't be done thourgh a set, because the order will be lost. This needs to be done in an array or a dictionnary (better), i.e. something like a table which stores face to face a color number and a thickness.
You've reused the bit of code I gave you earlier, but I don't think that's the right idea. There is a trick to understand what the code does, with the SURFACE_BY_COLOR rule.
When you write set1.addRule(myID, FGD_SURFACE_BY_COLOR), myID DOES NOT refer to a color, it refers to a surface. So the command means "I want you to fill set1 with all surfaces which have the same color as surface #myID."
This is not really intuitive and a bit tricky (or so I think) in the FEMAP API world, because usually the ID directly refers to what we point to. For ex with ELEM_BYPROP, you give the ID of a prop, not an element using a prop. But anyway...
Here's how I would solve your problem (NB: there are many ways to do this):
Sub Main Dim App As femap.model Set App = feFemap() Dim t As String Dim readFile As femap.Read Set readFile = App.feRead Dim s As femap.Surface Set s = App.feSurface Dim gr As femap.Group Set gr = App.feGroup Dim colorSet As femap.Set, sSet As femap.Set Set colorSet = App.feSet Set sSet = App.feSet Dim thickDict As Object Set thickDict = CreateObject("Scripting.Dictionary") '1) Read file If App.feFileGetName("Select File with FemapColorID","Text Files","*.txt",True,t) _ = FE_CANCEL Then End readFile.SetNoBlankLines(True) readFile.Open(t, 80) 'skip 2 lines readFile.Read : readFile.Read While Not readFile.AtEOF readFile.Read colorSet.Add(readFile.IntField(1,0)) thickDict.Add(readFile.IntField(1,0),readFile.IntField(2,0)) Wend readFile.Close '2) Create groups per color and name them While s.Next If colorSet.IsAdded(s.color) Then Set gr = App.feGroup sSet.Clear sSet.AddRule(s.ID,FGD_SURFACE_BYCOLOR) gr.SetAdd(FT_SURFACE,sSet.ID) gr.title = "Plate Thickness " & CStr(thickDict.item(s.color)) gr.Put(gr.NextEmptyID) colorSet.Remove(s.color) If colorSet.Count = 0 Then End End If Wend End Sub
NB: this works for a text file in which there are only 2 columns: color ID ans plate thickness.
A little explanation as to why I've coded this like this: because of the trick "anomaly" I"ve explained on the the SURFACE BY COLOR rule, I can't loop on colors: I need to loop on surfaces. But I only want to loop once on surfaces: as a rule a thumb keep in mind that a good code should loop as little as possible.
So i'm going to loop on surfaces (i.e. on surface IDs), which means I have no clue as to in which order I will encouter surfaces which have a color you are interested in. So I need to the plate thicknedd correspondance in an object which is robust with regard to this "no specific order" concept: that is exactly what the dictionnary does.
The before-last line makes sure that once I've dealt with a color I dont deal with it again.
The last line simply exits once we're done with all colors.
Because of the tricky bit this whole subject treads on advance programming considerations: code complexity and optimization and code robustness with regard to user input. For ex I have not asked you whether your text file lists ALL possible colors in model, or whether it is possible that a color appears in the text file but does not in the model - as the code is written it is robust to all that.
To answer your questions :
Yes there is a specific reason the group IDs appear cause i would like to seperate the sarface of color groups away from the others so that is why the group IDs appear so that then I wouldn't have to renumber is manually and the surfaces are grouped sequentially in an ascending order. And yes the text file does list all possible colors in the model.
I really appreciate all the help and the explanations make a big difference thanks a lot, although I just have one last question, when I ran the code the first two thickness in the textfile the thickness 2 which is correspondent to color ID 122 and thickness 4 which is correspondent to color ID 119, it did not group these two colors, why would that be ???