// to work in Visual Studio uncomment next line: public static void Main() // to use this code as Tekla macro uncomment next line: //public static void Run(Tekla.Technology.Akit.IScript akit) { //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Settings // <profile list>.csv - file location and name string csvLocation = "J:/Tekla/SKA_Macro files/stock list.csv"; // <profile list>.csv - delimeter string delimiterString = ";"; // list of part names for FL-PL profile check string[] partNamesToCheckArray = { "Afstivning", "Vind-X-Plade", "Løsdele", "Plade", "Fladstål", "Flange", }; // list of part names to include in name AND prefix swaping (should be Plade and Fladstal) string[] partNamesToSwapArray = { "Plade", "Fladstål" }; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // stock list.csv // // Instructions for preparation: // 1. you need original DS stock list, // 2. in excel delete all columns but 'Dimension', 'Reserveret' and 'Kvalitet'. This columns should be placed in A, B and C column positions, // 3. go through the rows and: // - delete the rows with missing material, // - repair the rows with corrupt material ('275' -> 'S275') // - delete or repair rows with corrupt profile values (look for stuff like: '12x150', '100*5', '15'). Correct formatting is: 'width thickness'. // 4. save the file as 'stock list.csv' (default delimeter is semicolon. You can change the delimiter in 'delimiterString' variable) // 5. save the file in the location set with 'csvLocation' variable. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Ideas for improvements // - add refresh selection button to message box 'Selected objects will be modified // - add 'working' icon to mouse //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // v1.2, 30.1.2016 // - more elaborate errors: added error catching for FileNotFoundException and DirectoryNotFoundException, // - now works also with files, that are currently open (have to check if this is tru also for in multiuser environments), //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // preparation of variables char delimeter = delimiterString[0]; List <string> partNamesToCheck = new List <string>(); partNamesToCheck.AddRange(partNamesToCheckArray); List <string> partNamesToSwap = new List <string>(); partNamesToSwap.AddRange(partNamesToSwapArray); // Profile list - profiles with attributes (width, thickness, material) // if profile is reserved it does not go in this list List <List <string> > profileList = new List <List <string> >(); profileList = csvReader(csvLocation, delimeter); // if clause to exit if csvReader didn't succeed if (profileList.Count == 0) { return; } Model Model = new Model(); if (!Model.GetConnectionStatus()) { MessageBox.Show("Tekla is not open.", Variables.caption); Environment.Exit(1); } // select object types for selector System.Type[] Types = new System.Type[2]; Types.SetValue(typeof(Beam), 0); Types.SetValue(typeof(ContourPlate), 1); // instantiate model object enumerator before if clauses Tekla.Structures.Model.ModelObjectEnumerator SelectedObjects = Model.GetModelObjectSelector().GetAllObjectsWithType(ModelObject.ModelObjectEnum.UNKNOWN); // ======================================================================================= // dialog for object selection DialogResult dr = new DialogResult(); mainForm form = new mainForm(); dr = form.ShowDialog(); if (dr == DialogResult.Yes) // 'Yes' is used for all objects { SelectedObjects = Model.GetModelObjectSelector().GetAllObjectsWithType(Types); } else if (dr == DialogResult.No) // 'No' is used to get selected objects { SelectedObjects = new Tekla.Structures.Model.UI.ModelObjectSelector().GetSelectedObjects(); } else { return; } // ======================================================================================= // list of changed objects ArrayList partList = new ArrayList(); while (SelectedObjects.MoveNext()) { var currentObject = SelectedObjects.Current; var nameOfObject = ""; var profileOfObject = ""; var prefixAssemblyOfObject = ""; var prefixPartOfObject = ""; bool isFlatProfile = false; // get name of the object currentObject.GetReportProperty("NAME", ref nameOfObject); // strip the name of brackets nameOfObject = nameOfObject.Replace("(", "").Replace(")", ""); // get the profile of the object currentObject.GetReportProperty("PROFILE", ref profileOfObject); // get the prefix of the object currentObject.GetReportProperty("ASSEMBLY_DEFAULT_PREFIX", ref prefixAssemblyOfObject); currentObject.GetReportProperty("PART_PREFIX", ref prefixPartOfObject); // check if profile is flat profile if (profileOfObject.StartsWith("FL") || profileOfObject.StartsWith("PL")) { isFlatProfile = true; } // if name is contained in the list of parts to check and profile is a flat profile go in if (partNamesToCheck.Contains(nameOfObject) && isFlatProfile) { // variables string objectMaterial = ""; double objectWidth = -1.0; double objectHeight = -1.0; double objectLength = -1.0; currentObject.GetReportProperty("MATERIAL", ref objectMaterial); currentObject.GetReportProperty("WIDTH", ref objectWidth); currentObject.GetReportProperty("HEIGHT", ref objectHeight); currentObject.GetReportProperty("LENGTH", ref objectLength); // check if profile is in stock list bool inStock = false; inStock = FLCheck(profileList, objectMaterial, objectWidth, objectHeight, objectLength); // check how profile should be changed bool changeToFL = false; bool changeToPL = false; if (inStock && profileOfObject.StartsWith("PL")) { changeToFL = true; } if (!inStock && profileOfObject.StartsWith("FL")) { changeToPL = true; } // check how name should be changed bool changeToFladstal = false; bool changeToPlade = false; // this is used to change prefixes bool changeToF = false; bool changeToC = false; if (partNamesToSwap.Contains(nameOfObject)) { if (inStock && nameOfObject.Replace("(", "").Replace(")", "") == "Plade") { changeToFladstal = true; } if (!inStock && nameOfObject.Replace("(", "").Replace(")", "") == "Fladstål") { changeToPlade = true; } if (inStock && (prefixPartOfObject != "F" || prefixAssemblyOfObject != "f")) { changeToF = true; } if (!inStock && (prefixPartOfObject != "C" || prefixAssemblyOfObject != "c")) { changeToC = true; } } // Functionality for changing the atributes is doubled for beams and plates. // Could this be done in one clause? Beam beam = SelectedObjects.Current as Beam; if (beam != null) { if (changeToFL) { beam.Profile.ProfileString = "FL" + beam.Profile.ProfileString.ToString().Remove(0, 2); } if (changeToPL) { beam.Profile.ProfileString = "PL" + beam.Profile.ProfileString.ToString().Remove(0, 2); } if (changeToFladstal) { beam.Name = "Fladstål"; } if (changeToF) { beam.AssemblyNumber.Prefix = "f"; beam.PartNumber.Prefix = "F"; } if (changeToPlade) { beam.Name = "Plade"; } if (changeToC) { beam.AssemblyNumber.Prefix = "c"; beam.PartNumber.Prefix = "C"; } // add parts to the list of modified parts if (changeToFL || changeToPL || changeToFladstal || changeToPlade || changeToC || changeToF) { partList.Add(beam); } } ContourPlate plate = SelectedObjects.Current as ContourPlate; if (plate != null) { if (changeToFL) { plate.Profile.ProfileString = "FL" + plate.Profile.ProfileString.ToString().Remove(0, 2); } if (changeToPL) { plate.Profile.ProfileString = "PL" + plate.Profile.ProfileString.ToString().Remove(0, 2); } if (changeToFladstal) { plate.Name = "Fladstål"; } if (changeToF) { plate.AssemblyNumber.Prefix = "f"; plate.PartNumber.Prefix = "F"; } if (changeToPlade) { plate.Name = "Plade"; } if (changeToC) { plate.AssemblyNumber.Prefix = "c"; plate.PartNumber.Prefix = "C"; } // add parts to the list of modified parts if (changeToFL || changeToPL || changeToFladstal || changeToPlade) { partList.Add(plate); } } } } // select objects that are in list for modification Tekla.Structures.Model.UI.ModelObjectSelector mos = new Tekla.Structures.Model.UI.ModelObjectSelector(); mos.Select(partList); // modified object count var modCount = 0; var errCount = 0; // exit if there is no parts to modify if (partList.Count != 0) { // confirm modification DialogResult dialogResult = MessageBox.Show(new Form { TopMost = true }, "Selected objects will be modified.", Variables.caption, MessageBoxButtons.OKCancel); if (dialogResult == DialogResult.OK) { // if OK, then go through list and modify each part Tekla.Structures.Model.ModelObjectEnumerator selObjEnum = Model.GetModelObjectSelector().GetAllObjectsWithType(ModelObject.ModelObjectEnum.CONTOURPLATE); selObjEnum = new Tekla.Structures.Model.UI.ModelObjectSelector().GetSelectedObjects(); // modify only objects that are in part list for modification and in current selection while (selObjEnum.MoveNext()) { foreach (var part in partList) { Beam beam = part as Beam; if (beam != null && selObjEnum.Current.Identifier.ToString() == beam.Identifier.ToString()) { if (!beam.Modify()) { errCount++; } else { modCount++; } } ContourPlate plate = part as ContourPlate; if (plate != null && selObjEnum.Current.Identifier.ToString() == plate.Identifier.ToString()) { if (!plate.Modify()) { errCount++; } else { modCount++; } } } } if (errCount != 0) { MessageBox.Show("Warning\n# of objects which didn't modify:\n" + errCount + "\n\n# of changed objects:\n" + modCount, Variables.caption); } else { MessageBox.Show("# of changed objects:\n" + modCount, Variables.caption); } } else if (dialogResult == DialogResult.Cancel) { return; } } else { MessageBox.Show("No parts to modifiy found.", Variables.caption); } }
// to work in Visual Studio uncomment next line: public static void Main() // to use this code as Tekla macro uncomment next line: //public static void Run(Tekla.Technology.Akit.IScript akit) { //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Settings //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Model Model = new Model(); // select object types for selector System.Type[] Types = new System.Type[2]; Types.SetValue(typeof(Beam), 0); Types.SetValue(typeof(ContourPlate), 1); // instantiate model object enumerator before if clauses Tekla.Structures.Model.ModelObjectEnumerator SelectedObjects = Model.GetModelObjectSelector().GetAllObjectsWithType(ModelObject.ModelObjectEnum.UNKNOWN); // ======================================================================================= // dialog for object selection DialogResult dr = new DialogResult(); mainForm form = new mainForm("Set user phase for:", "All", "Selected"); dr = form.ShowDialog(); if (dr == DialogResult.Yes) // 'Yes' is used for all objects { SelectedObjects = Model.GetModelObjectSelector().GetAllObjectsWithType(Types); } else if (dr == DialogResult.No) // 'No' is used to get selected objects { SelectedObjects = new Tekla.Structures.Model.UI.ModelObjectSelector().GetSelectedObjects(); } else { return; } // ======================================================================================= // list of changed objects ArrayList partList = new ArrayList(); while (SelectedObjects.MoveNext()) { var currentObject = SelectedObjects.Current; var currObjPhaseComment = ""; var currObjUserPhase = ""; Phase currObjPhase = new Phase(); currentObject.GetPhase(out currObjPhase); // phase comment gets copied to user phase currObjPhaseComment = currObjPhase.PhaseComment; currentObject.GetUserProperty("USER_PHASE", ref currObjUserPhase); if (currObjUserPhase != currObjPhaseComment) { //currentObject.SetUserProperty("USER_PHASE", currObjPhaseComment); partList.Add(currentObject); } } // select objects that are in list for modification Tekla.Structures.Model.UI.ModelObjectSelector mos = new Tekla.Structures.Model.UI.ModelObjectSelector(); mos.Select(partList); // modified object count var modCount = 0; var errCount = 0; // exit if there is no parts to modify if (partList.Count != 0) { // confirm modification DialogResult drConfirmation = new DialogResult(); mainForm formConfirmation = new mainForm("Selected objects will be modified", "Refresh", "Ok"); drConfirmation = formConfirmation.ShowDialog(); if (drConfirmation == DialogResult.Yes) // 'Yes' is used to refresh selection { mos.Select(partList); } else if (drConfirmation == DialogResult.No) // 'No' is used to confirm { // if OK, then go through list and modify each part Tekla.Structures.Model.ModelObjectEnumerator selObjEnum = Model.GetModelObjectSelector().GetAllObjectsWithType(ModelObject.ModelObjectEnum.CONTOURPLATE); selObjEnum = new Tekla.Structures.Model.UI.ModelObjectSelector().GetSelectedObjects(); // modify only objects that are in part list for modification and in current selection while (selObjEnum.MoveNext()) { foreach (var part in partList) { Beam beam = part as Beam; ContourPlate plate = part as ContourPlate; if (beam != null && selObjEnum.Current.Identifier.ToString() == beam.Identifier.ToString() || plate != null && selObjEnum.Current.Identifier.ToString() == plate.Identifier.ToString()) { try { var currentObject = selObjEnum.Current; var currObjPhaseComment = ""; var currObjUserPhase = ""; Phase currObjPhase = new Phase(); currentObject.GetPhase(out currObjPhase); // phase comment gets copied to user phase currObjPhaseComment = currObjPhase.PhaseComment; currentObject.GetUserProperty("USER_PHASE", ref currObjUserPhase); if (currObjUserPhase != currObjPhaseComment) { currentObject.SetUserProperty("USER_PHASE", currObjPhaseComment); } modCount++; } catch { errCount++; } } } } if (errCount != 0) { MessageBox.Show("Warning\n# of objects which didn't modify:\n" + errCount + "\n\n# of changed objects:\n" + modCount, "FLPL checker"); } else { MessageBox.Show("# of changed objects:\n" + modCount, "FLPL checker"); } } else { return; } } else { MessageBox.Show("No parts to modifiy found.", Globals.appName); } }