PenelopeSkye 1 Posted February 8, 2023 I have a Data Module where it is impossible to find objects, see attached screenshot. I inherited it in this state. I just have to scroll through the objects in the structure pane to find anything. I would like to create a second Data Module file and move some of the database objects that I work with most frequently. Does anyone have any instructions to do this? I would love to start cutting and pasting but I am quite sure it can't be that simple! Thanks! Share this post Link to post
programmerdelphi2k 237 Posted February 8, 2023 (edited) WOW! That's very crazy man! in Text mode, you can find and copy/paste in second "place" (DM)... of course, very tiring, but given this tangle of objects, nothing will be very easy and reliable in an automation without any human intervention. because after copy your obj, of couse, needs pay attention on events code... in DFM mode, copy it too! 🤣 Edited February 8, 2023 by programmerdelphi2k Share this post Link to post
Uwe Raabe 2057 Posted February 8, 2023 Actually you CAN just copy/cut and paste the controls to another datamodule, but any event handlers and some links can get lost. I suggest to copy the event handlers in the pas file first and then copy the controls in the designer. That way they are re-wired in the target module. Also make sure that you always copy all related components like a datasource linked to a query or vice versa in master-detail relations. Whatever you do, make sure you can re-establish the original state if anything went wrong. Share this post Link to post
Stano 143 Posted February 8, 2023 I would try another way. To gradually create individual objects dynamically if necessary. One of the possibilities is to find out where a specific object is used everywhere. Then decide accordingly. If it is used only in one place, then there is nothing to think about. But it is a very laborious procedure. It is estimated that there are around 500 objects It is not normal! 2 Share this post Link to post
PenelopeSkye 1 Posted February 8, 2023 Thank you everyone! I am going to just start moving one object at a time as I work with them, find out where it is used and act accordingly. Share this post Link to post
programmerdelphi2k 237 Posted February 8, 2023 (edited) You could try something along these lines: you create a new "DataModule in your project" (thus, Delphi already creates the .PAS unit and the .DFM file! = more easy way! Now, you can use a procedure like the one below to read the components you want to remove from the source-datamodule and insert them into your new datamodule created above! Remembering that "InsertComponent()" will automatically try to remove the component from the source to insert it in the target! type TMyArrayOfThisComponents = TArray<string>; procedure MyInsertAllComponentsOnDM(const ADMsource, ADMtarget: TDataModule); begin while (ADMsource.ComponentCount > 0) do ADMtarget.InsertComponent(ADMsource.Components[0]); // "remove" from source and "insert" on target! end; procedure MyInsertThisComponentsOnDM(const ADMsource, ADMtarget: TDataModule; const AComponents: TMyArrayOfThisComponents); begin for var C in AComponents do // all list of components names... begin for var i: integer := 0 to (ADMsource.ComponentCount - 1) do if (ADMsource.Components[i].Name = C) then // if exists on DMsource... begin ADMtarget.InsertComponent(ADMsource.Components[i]); // "remove" from source and "insert" on target // break; // next components-name... end; end; end; procedure TForm1.BtnUsingDMonProjectClick(Sender: TObject); begin try // DataModule3/Unit3 is a DataModule created on this project, for example! // // MyInsertAllComponentsOnDM(DataModule2, DataModule3); MyInsertThisComponentsOnDM(DataModule2, DataModule3, ['FDQuery1', 'FDConnection', 'dsQuery1', '...']); // WriteComponentResFile('Unit3.dfm', DataModule3); // Unit3.pas and Unit3.DFM "already" exists in your project!!! except // ??? end; end; procedure TForm1.BtnCreatingAnewDMfileClick(Sender: TObject); var MyNewDM: TDataModule; begin MyNewDM := TDataModule.Create(nil); try MyNewDM.Name := 'MyNewDM'; try // MyInsertAllComponentsOnDM(DataModule2, MyNewDM); MyInsertThisComponentsOnDM(DataModule2, MyNewDM, ['FDQuery1', 'FDConnection', 'dsQuery1', '...']); // WriteComponentResFile('MyNewDM.dfm', MyNewDM); // // now, you needs create your "UNIT.pas" for this "MyNewDM.DFM file" like IDE do it! except // ??? end; finally MyNewDM.Free; end; end; now, you'll have your components inserted in your "new datamodule", then, you can just "ADD it" in your project, and create your "event" (or copy it from old datamodule) in the tests, the properties are kept as in the source! you would can automatizate this, but needs much more code to verify each object and your events, ...read source, write target ... Edited February 8, 2023 by programmerdelphi2k 1 Share this post Link to post
Attila Kovacs 629 Posted February 8, 2023 1. Crerate a list of the components on thedataset 2. Clone the datamodul with a filemanagaer (copy pas and dfm, rename unit name and datamodul class in the pas and at the top of the dfm) 3. now pick a group from the list and keep only them on the 2nd datamodul, delete the others 4. start refactoring the project 5. goto 2. 1 Share this post Link to post
aehimself 396 Posted February 8, 2023 +1 for @Stano's idea. At a large number like this it's better to write a factory code and request these items runtime. 1 Share this post Link to post
Attila Kovacs 629 Posted February 8, 2023 19 minutes ago, aehimself said: +1 for @Stano's idea. At a large number like this it's better to write a factory code and request these items runtime. Good luck with that on a giant legacy project where the DAC's with its fields and co. are living at the visual level an they are also used to it. Share this post Link to post
aehimself 396 Posted February 8, 2023 We are developing a 20 year old application at work: over 1,5M LOC, 500-700 frames, couple thousands of units. Today we had a meeting with our teamlead where we successfully convinced him to allow the framework team to go for a full visual and codebase refactoring - effectively building it from the ground up once more; reusing mostly experience and tiny chunks of the original code (yeah, it's that bad). There are things what you can not delay any further. If this is what is needed to improve the coding experience devs will have to get used to the new model. It's for their own sake aswell, after all. With all that said, I'm fully aware that OP probably won't go in this direction. I'm leaving my remark here for future visitors, who might still be able to change their design seeing what the easy way can / will cause. 2 Share this post Link to post
Anders Melander 1783 Posted February 8, 2023 1 hour ago, aehimself said: go for a full visual and codebase refactoring - effectively building it from the ground up once more 1 Share this post Link to post
Fr0sT.Brutal 900 Posted February 9, 2023 (edited) In fact, Delphi teaches us bad things with all this visual & RAD button-dropping. It's good for small apps but when they grow, old habits remain and lead to these nightmare. I was in the same situation with an app started when I started learning Delphi so it's evolving with me. In that app I significantly reduced the number of objects in datamodules by changind all temporary queries (that is, those which do not have any datasource attached) from design-time components to temporary objects created at run-time. Their SQLs are defined as literals in datamodule unit and field list is generated dynamically. And with interface-based wrapper the code is pretty simple with GetTempQuery(Database).Q do begin SQL.Text := SQL_Insert; Params ... ExecSQL; end; Edited February 9, 2023 by Fr0sT.Brutal 3 Share this post Link to post
PenelopeSkye 1 Posted February 9, 2023 As I read each successive text I would think - I'll try that! Then the next Idea was also good! I'm going to try Programmers code. I am not the most experienced Pascal developer so I may not be able to make it work. If I can't I will clone the current data module but also see if I can easily create the objects at run-time. If I can ever build it from the ground up it will be in C#!!!! Thanks again everyone! Share this post Link to post
weirdo12 19 Posted February 9, 2023 (edited) 1. Open the project. 2. Open the TDataModule source file. 3. Change the Name property of the TDataModule to a new unique name. 3. Click File > Save As... and save it with a new file name. 4. Add the original TDataModule back to the project. In the new TDataModule you can start deleting components and event handlers. 1. Select the component you want to delete. 2. In the Object inspector, click the Events tab. 3. For any events that have been created for the component, double-click the event handler name. 4. Delete the code within the event handler BUT DO NOT delete the event handler. procedure TForm1.DataSource1DataChange(Sender: TObject; Field: TField); begin // delete the code in here but // leave everything between procedure and end; end; 5. Click File > Save and the handler will be removed. Edited February 9, 2023 by weirdo12 Share this post Link to post
Fr0sT.Brutal 900 Posted February 10, 2023 (edited) Don't forget to check if deleted component is referred by other components! On delete these refs just get emptied silently. Form view as text will help on this. Anyway form text view helps much because you can see all non-default properties of a component including event handlers. Then do text search by component name to find all refs Edited February 10, 2023 by Fr0sT.Brutal Share this post Link to post
Lars Fosdal 1792 Posted February 10, 2023 On 2/9/2023 at 12:54 AM, Anders Melander said: or Retire. Sometimes, there is new software out there that can do the job. Share this post Link to post
Lars Fosdal 1792 Posted February 10, 2023 I never liked the visual data module. I'd prefer it to have a listview of components rather than a collection of icons. On event handlers. Assign them in code. They break so easily otherwise. Share this post Link to post
Attila Kovacs 629 Posted February 10, 2023 1 hour ago, Lars Fosdal said: I never liked the visual data module. It's the RAD from RAD Studio. I remember at the CeBIT 99 or 2000, Borland presentation, ~click click ctrlA click click drag&drop and the form was filled with the dbcontrols. Share this post Link to post
PenelopeSkye 1 Posted February 13, 2023 I am definitely not fond of the data module. And I am also concerned about all the various places these objects are referred to. It has been a learning process! Share this post Link to post
programmerdelphi2k 237 Posted February 13, 2023 on code it's more easy find it... just rename your "data module unit" and try re-compile it... you'll see many errors on compiling... on components you need open each "form/datamodule" to see what component (ex. Datasets) use it! or open the form/datamodule as TEXT and find the name Share this post Link to post