Treplos Posted October 16, 2013 Share Posted October 16, 2013 (edited) JobVanDam, I don't know if this would help but one way I indirectly do that is by using my export selection script. It exports records of all entries in your selection (whole mod, or specific sub categories). The trick is to open the file in something like NotePad++ and look at the line numbers, which should tell you how many items there are (remember to remove empty lines). The script below should export FormID + EditorID + Full Name, or you can tweak it to export other data. Also, another way is to look at the system messages like:[Apply Script done] Processed Records: 8, Elapsed Time: 00:00. <-- this mod has 8 records. I'm sure there are other, simple or better ways that the experts here may tell you about ;P { Print records of a selection in any order, A-Z or Z-A. By Rezel (Treplos) // ReverseSort Procedure by Zilav. Hotkey: Ctrl+P } Unit Userscript; var FName: string; slPrint: TStringList; //=========================================================================== Function Initialize: Integer; Begin slPrint := TStringList.Create; //slPrint.Sorted := True; End; //=========================================================================== Function Process(e: IInterface): Integer; Begin // ------------------------------------------- // Choose what data to print: comment out the line you don't want & uncomment the one you want. // ------------------------------------------- // (1) FormID + EditorID + Full Name slPrint.Add(IntToHex(FixedFormID(e), 8) + ' ; ' + GetElementEditValues(e, 'EDID') + ' ; ' + GetElementEditValues(e, 'FULL')); // (2) FormID + EditorID // slPrint.Add(IntToHex(FixedFormID(e), 8) + ' ; ' + GetElementEditValues(e, 'EDID')); // (3) EditorID + Full Name // slPrint.Add(GetElementEditValues(e, 'EDID') + ' ; ' + GetElementEditValues(e, 'FULL')); // (4) Mod Name // slPrint.Add(GetFileName(GetFile(e))); // (5) EditorID // slPrint.Add(GetElementEditValues(e, 'EDID')); // (6) Full Name // slPrint.Add(GetElementNativeValues(e, 'FULL')); // slPrint.Add(GetElementEditValues(e, 'FULL')); End; //=========================================================================== Procedure ReverseSort(slPrint: TStringList); var i: integer; s: string; begin slPrint.Sort; for i := 0 to slPrint.Count div 2 - 1 do begin s := slPrint[i]; slPrint[i] := slPrint[slPrint.Count-i-1]; slPrint[slPrint.Count-i-1] := s; end; end; //=========================================================================== Function Finalize: Integer; Begin // ------------------------------------------- // Choose your sorting method // ------------------------------------------- // Sort A-Z --> Leave as default. slPrint.Sort; // Sort Z-A --> Uncomment to get reverse Z-A sorting. //ReverseSort(slPrint); //FName := '%USERPROFILE%\My Documents\' + '-- Export.txt'; FName := ProgramPath + '-- Export.txt'; slPrint.SaveToFile(FName); AddMessage('>>> Saving list to ' + FName); slPrint.Free; Result := 1; End; End. Edited October 16, 2013 by Treplos Link to comment Share on other sites More sharing options...
JobVanDam Posted October 19, 2013 Share Posted October 19, 2013 Is there anything that will automatically count all the items in any list so I don't have to?Annoying sometimes to have count each item myself sometimes to ensure i enter the correct number of items in a list. When you say "List" what do you mean?StringLists in pascal code?Arrays in pascal code?Records in a group (with a signature) in TES5Edit?Elements in a container in TES5Edit?Records after filtering? - M Sorry, I was referring to the number of items in a leveled list or the numbers of items an NPC has etc. TreplosThanks, I will try that script out and see how it goes. Link to comment Share on other sites More sharing options...
DanielUA Posted October 19, 2013 Share Posted October 19, 2013 (edited) You have two thens at line "if Name(..."It was a copy-paste mistake. Solved it.I don't think it's a good idea to use Name for filenames. Use GetFileName() Done You don't need to store the copyfile as an IInterface object, you only need the file name, which should be a global string variable.Sorry but I don't understand how. 'f' is IwbFile so 'copyfile' must be IwbFile too. Am I wrong? Fix your indentation, please, it's difficult to read because it's all wrong.Put an empty line between functions, this also helps with readability.DoneAnd about troubleshooting. Looks like the only problem is with "Process" function. I don't get even "Start matching names" message. Here is my code now unit userscript; var s1, slPath: string; i: integer; f, ovrec, copyfile: IInterface; function Initialize: integer; begin // initialize your stuff here // use InputBox to accept user input for filename, then use a loop to find that file and store it in a variable. I do this in several of my scripts. // use a looping InputBox until the input is empty to add paths the user wants to copy things from to a stringlist: slPaths s1 := InputBox('File','Enter the name of the file containing the record you want to copy an element from, including the file extension','Skyrim.esm'); for i := 0 to FileCount - 1 do begin f:= FileByIndex(i); AddMessage('Checking file '+GetFileName(f)); if SameText(s1, GetFileName(f)) then begin copyfile := f; AddMessage('File is '+GetFileName(copyfile)); Break; end; end; slPath := InputBox('Path', 'Enter path you want to copy', ''); AddMessage('Path is '+slPath); //here i have not array of pathes but only one. That's what i need end; function Process(e: IInterface): integer; begin AddMessage('Start Process function'); for i := 0 to OverrideCount(e) - 1 do begin AddMessage('Start matching names'); if GetFileName(GetFile(OverrideByIndex(e, i))) = GetFileName(copyfile) then begin AddMessage('Names match'); ovrec := OverrideByIndex(e, i); AddMessage('ovrec assigned: '+GetElementEditValues(ovrec, 'EDID')); Break; end; end; wbCopyElementToRecord(e, ElementByPath(ovrec, slPath), True, True); //changeg first boolean to False because it is referred as "aAsNew"... And what i need is to replace old record (weight or price), not to add something new. //doesn't work both with True of False anyway end; end. I hope I don't bore you too much matortheeternalI'm just really limited with my time, and this script is all I need to continue development of my mod (which I'm still intending to continue).So I just have to hope that you consider helping me with it... And of course I'll understand if you don't want to bother with it. Edited October 19, 2013 by DanielUA Link to comment Share on other sites More sharing options...
matortheeternal Posted October 21, 2013 Author Share Posted October 21, 2013 (edited) And about troubleshooting. Looks like the only problem is with "Process" function. I don't get even "Start matching names" message. Here is my code now You're selecting several records, then right clicking, then applying the script? Process function only runs on selected records. If you are selecting records than that is odd, and I'll have to try it out myself to see what's going on. unit userscript; var s1, slPath: string; i: integer; f, ovrec, copyfile: IInterface; function Initialize: integer; begin // initialize your stuff here // use InputBox to accept user input for filename, then use a loop to find that file and store it in a variable. I do this in several of my scripts. // use a looping InputBox until the input is empty to add paths the user wants to copy things from to a stringlist: slPaths s1 := InputBox('File','Enter the name of the file containing the record you want to copy an element from, including the file extension','Skyrim.esm'); for i := 0 to FileCount - 1 do begin f:= FileByIndex(i); AddMessage('Checking file '+GetFileName(f)); if SameText(s1, GetFileName(f)) then begin copyfile := f; AddMessage('File is '+GetFileName(copyfile)); Break; end; end; slPath := InputBox('Path', 'Enter path you want to copy', ''); AddMessage('Path is '+slPath); //here i have not array of pathes but only one. That's what i need end; function Process(e: IInterface): integer; begin AddMessage('Start Process function'); for i := 0 to OverrideCount(e) - 1 do begin AddMessage('Start matching names'); if GetFileName(GetFile(OverrideByIndex(e, i))) = GetFileName(copyfile) then begin AddMessage('Names match'); ovrec := OverrideByIndex(e, i); AddMessage('ovrec assigned: '+GetElementEditValues(ovrec, 'EDID')); Break; end; end; wbCopyElementToRecord(e, ElementByPath(ovrec, slPath), True, True); //changeg first boolean to False because it is referred as "aAsNew"... And what i need is to replace old record (weight or price), not to add something new. //doesn't work both with True of False anyway end; end. I'll test out this code and let you know what I figure out. I hope I don't bore you too much matortheeternal Naw man, I'm happy to help. ;)Sorry it took so long to respond, I was on a trip. I'm just really limited with my time, and this script is all I need to continue development of my mod (which I'm still intending to continue).So I just have to hope that you consider helping me with it... And of course I'll understand if you don't want to bother with it. I'll see to it that you finish it. Edit: it appears OverrideByIndex may be broken. Either that, or I'm using it wrong.Edit 2: will do some more testing and stuff today. we could use RecordByFormID if we can't figure out why OverrideByIndex isn't working. Edited October 21, 2013 by matortheeternal Link to comment Share on other sites More sharing options...
DanielUA Posted October 21, 2013 Share Posted October 21, 2013 Looking forward to it :) Link to comment Share on other sites More sharing options...
matortheeternal Posted October 23, 2013 Author Share Posted October 23, 2013 Looking forward to it :smile: I think I figured it out. Silly me. I need to get the master record before I can use OverrideCount and OverrideByIndex. Those commands find the override records of a main/baserecord, so running them on an override record doesn't work. Silly me. I'll get to this later today. Link to comment Share on other sites More sharing options...
matortheeternal Posted October 23, 2013 Author Share Posted October 23, 2013 (edited) DanielUA: Script is working 100%. unit userscript; var s1, sPath: string; i: integer; f, ovRec, copyfile: IInterface; function Initialize: integer; begin // initialize your stuff here // use InputBox to accept user input for filename, then use a loop to find that file and store it in a variable. I do this in several of my scripts. // use a looping InputBox until the input is empty to add paths the user wants to copy things from to a stringlist: sPaths s1 := InputBox('File','Enter the name of the file containing the record you want to copy an element from, including the file extension','Skyrim.esm'); for i := 0 to FileCount - 1 do begin f := FileByIndex(i); AddMessage('Checking file '+GetFileName(f)); if SameText(s1, GetFileName(f)) then begin copyfile := f; AddMessage('File is '+GetFileName(copyfile)); Break; end; end; sPath := InputBox('Path', 'Enter path you want to copy', ''); AddMessage('Path is '+sPath); //here i have not array of pathes but only one. That's what i need end; function Process(e: IInterface): integer; var i: integer; mRec: IInterface; begin AddMessage('Processing'+Name(e)); mRec := MasterOrSelf(e); // skip if record is master (the script can only be run on override records) if Equals(mRec, e) then begin AddMessage('Selected record: '+Name(e)+' is a base record, skipping.'); exit; end; // check if master record is the one user wanted to copy values from if GetFileName(GetFile(mRec)) = GetFileName(copyfile) then begin AddMessage(' Copying values from master record.'); if not SameText(GetElementEditValues(e, sPath), '') then AddMessage(' Value at path: '+sPath+' changed from: '+GetElementEditValues(e, sPath)+' to: '+GetElementEditValues(mRec, sPath)) else AddMessage(' Value at path: '+sPath+' restored.'); wbCopyElementToRecord(ElementByPath(mRec, sPath), e, False, True); end else begin // look for a lower override to copy values from for i := 0 to OverrideCount(mRec) - 1 do begin AddMessage(' Looking for override record...'); if GetFileName(GetFile(OverrideByIndex(mRec, i))) = GetFileName(copyfile) then begin AddMessage(' Found override record.'); ovRec := OverrideByIndex(mRec, i); AddMessage(' ovRec assigned: '+GetElementEditValues(ovRec, 'EDID')); Break; end; end; if not SameText(GetElementEditValues(e, sPath), '') then AddMessage(' Value at path: '+sPath+' changed from: '+GetElementEditValues(e, sPath)+' to: '+GetElementEditValues(ovRec, sPath)) else AddMessage(' Value at path: '+sPath+' restored.'); wbCopyElementToRecord(ElementByPath(ovRec, sPath), e, False, True); end; end; end. Edit: Incorporated into QuickChange. Will have a link to QuickChange v1.7 in a minute. Edit 2: QuickChange v1.7. Right Click -> Save Link As. Edited October 23, 2013 by matortheeternal Link to comment Share on other sites More sharing options...
matortheeternal Posted October 23, 2013 Author Share Posted October 23, 2013 Working on Armor Mod Builder. :D After it's done I'll have only one or two more scripts to finish up. QuickDisplay and something else (I honestly don't remember?) Then we'll see the release of this awesome package of scripts for TES5Edit... :smile: Link to comment Share on other sites More sharing options...
DanielUA Posted October 25, 2013 Share Posted October 25, 2013 mator, thank you!!! I'm really happy to finally have and use this script. Makes everything so much easier.And immediately a bugreport :)Everything worked perfect for me when I tried to copy DATA\Weight from Skyrim.esm to my esp.But when I tried to copy it from another esp (Weapon and Armor fixes Remade) I had mistake:"List index out of bounds (3)." Link to comment Share on other sites More sharing options...
matortheeternal Posted October 25, 2013 Author Share Posted October 25, 2013 (edited) mator, thank you!!! I'm really happy to finally have and use this script. Makes everything so much easier.And immediately a bugreport :smile:Everything worked perfect for me when I tried to copy DATA\Weight from Skyrim.esm to my esp.But when I tried to copy it from another esp (Weapon and Armor fixes Remade) I had mistake:"List index out of bounds (3)." Hmm... 3 is way too high for OverrideByIndex. It should be more like 0, or something. I'll look into this. Edited October 25, 2013 by matortheeternal Link to comment Share on other sites More sharing options...
Recommended Posts