Wish ABMaterial - CRUD Form Builder (Designer)

Harris

Well-Known Member
Licensed User
Much time is spent creating (input) forms in ABM. It is a repetitive process.

First one must create the raw sheet: BuildCompanyInputSheet() As ABMModalSheet

B4X:
Dim userinp As ABMModalSheet
    userinp.Initialize(page, "companyinp", False, False)
    userinp.IsDismissible = False

Note
: "companyinp" is now our unique public reference (within page), whereas userinp is the local.

Here we first setup how many rows we need and the cell layout for each.
B4X:
  userinp.Content.AddRowsM(1, True,0,0, "").AddCells12(1,"")

    ' Used as a title bar (" Provide info for this company")
    userinp.Content.AddRowsM(4, True,0,0, "").AddCellsOS(1,0,0,0, 6,6,6,"").AddCellsOS(1,0,0,0,6,6,6,"")
   ' add 4 (x) rows with 2 cells - used for data fields
    userinp.Content.AddRowsM(1, True,0,0, "").AddCells12(1,"")
   ' add extra rows for anything you want now - or in the future.
    userinp.Content.BuildGrid   ' IMPORTANT
Many rows can be added (with different cell layouts), but until they are used, they have no affect.

Next we add components to the row grid - for each cell.

B4X:
Dim inpName As ABMInput
    inpName.Initialize(page, "compemail", ABM.INPUT_TEXT, "User Email", False, "lightblue")
    userinp.Content.Cell(2,1).AddComponent(inpName)
  
    Dim inpowner As ABMInput
    inpowner.Initialize(page, "compowner", ABM.INPUT_TEXT, "Owner Name", False, "lightblue")
    userinp.Content.Cell(2,2).AddComponent(inpowner)
Here you specify the component for each row and cell.

NOW we introduce a GUI form to help us create the ADD, UPDATE/MODIFY, DELETE.

Within, one defines which type of input, what the unique name is and what the title is along with a theme.

Assuming the Primary Key is always at position 0 (of the Select), AND we need a select statement for the items we wish to ADD or EDIT - we need to connect to the DB and table in question - to expose the fields we can include.

We also need a footer. Usually, it is Save or Cancel...

I am thinking much of this can be created dynamically with an input form designer (or not).

Any thoughts?

Thanks
 

alwaysbusy

Expert
Licensed User
I'm thinking about some kind of 'Generator' methods. They do not modify your code but generate .txt files so you can copy/paste code into your project.
(Note: 1.06 will be released early next week and this will not make it earliest until 1.07!

Example what it could do if you want to generate B4J code for a message box:

You type:

B4X:
ABM.GenerateB4JCodeMessageBox(File.DirApp, "MyQuestion", "Do You want this in ABMaterial?", "Yes", "No", "Don't care")
Run the app and a file called 'MyQuestion.txt" will be generated in your DirApp folder looking like this:

B4X:
--------------------------------------------------------------
' Add in BuildPage()
--------------------------------------------------------------
page.AddModalSheetTemplate(BuildMyQuestion)

--------------------------------------------------------------
' Add in the class
--------------------------------------------------------------
Sub BuildMyQuestion() As ABMModalSheet
    Dim msgMyQuestion As ABMModalSheet
    msgMyQuestion.Initialize(page, "MyQuestion", False, False)
    msgMyQuestion.IsDismissible = False

    msgMyQuestion.Content.AddRowsM(1, True,0,0, "").AddCells12(1, "")
    msgMyQuestion.Content.BuildGrid

    ' add label
    Dim lblMyQuestion As ABMLabel
    lblMyQuestion.Initialize(page, "lblMyQuestion", "Do You want this in ABMaterial?" , ABM.SIZE_PARAGRAPH, False, "")
    msgMyQuestion.Content.CellR(0,1).AddComponent("lblMyQuestion")

    msgMyQuestion.Footer.AddRowsM(1,True,0,0, "").AddCellsOS(1,6,6,6,3,3,3,"").AddCellsOS(1,0,0,0,3,3,3, "")
    msgMyQuestion.Footer.BuildGrid 'IMPORTANT once you loaded the complete grid AND before you start adding components

    ' create the buttons for the footer
    Dim msgyes As ABMButton
    msgyes.InitializeFlat(page, "MyQuestionYes", "", "", "Yes", "transparent")
    msgMyQuestion.Footer.Cell(1,1).AddComponent(msgyes)

    Dim msgno As ABMButton
    msgno.InitializeFlat(page, "MyQuestionNo", "", "", "No", "transparent")
    msgMyQuestion.Footer.Cell(1,2).AddComponent(msgno)

    Dim msgcancel As ABMButton
    msgcancel.InitializeFlat(page, "MyQuestionCancel", "", "", "Don't care", "transparent")
    msgMyQuestion.Footer.Cell(1,2).AddComponent(msgcancel)

    Return msgMyQuestion
End Sub

Sub MyQuestionYes_Clicked(Target As String)

End Sub

Sub MyQuestionNo_Clicked(Target As String)

End Sub

Sub MyQuestionCancel_Clicked(Target As String)

End Sub

--------------------------------------------------------------
' calling the message box in your code
--------------------------------------------------------------
Dim msgMyQuestion As ABMModalSheet = page.ModalSheet("msgMyQuestion")
Dim lblMyQuestion As ABMLabel = msg.Content.Component("lblMyQuestion")
lblMyQuestion.Text = "PUTHEREYOURMESSAGE"
page.ShowModalSheet("msgMyQuestion")
--------------------------------------------------------------
Now, you can copy & paste the code into your real B4J project and modify what is needed.

Of course, for a CRUD form, giving a releative simple definition, this could generate tons of code for you.

Let me know how you all feel about this.

Alwaysbusy
 

alwaysbusy

Expert
Licensed User
Pondering a little further on the CRUD generator. I think I can write all hundreds of lines of code to build the sheet, handle view, new, update and delete actions on a table with a simple 10 step definition. Something looking like this (subject to change of course, still just in 'think-tank' phase):

B4X:
Dim MyModalDef As ABMGeneratorCRUDDefinition
MyModalDef.Initialize("caseID", "tCases", "My Case", "Save", "Cancel")
MyModalDef.Set01FieldNames(     Array As String ("caseID"         , "caseSummary"    , "caseRank"            , "caseDescription"    ))
MyModalDef.Set02RowOffsetSizes( Array As String (""               , "1:0:9"          , "1:0:3"               , "2:0:12"             ))
MyModalDef.Set03LabelTexts(     Array As String (""               , "Summary"        , "Rank"                , "Description"        ))
MyModalDef.Set04DefaultValues(  Array As String (""               , ""               , ""                    , "ret0"               ))
MyModalDef.Set05ComponentTypes( Array As Int    (ABM.CRUDTYPE_NONE, ABM.CRUDTYPE_TEXT, ABM.CRUDTYPE_COMBOLIST, ABM.CRUDTYPE_TEXTAREA))
MyModalDef.Set06UseInInserts(   Array As Boolean(False            , True             , True                  , True                 ))
MyModalDef.Set07UseInUpdates(   Array As Boolean(False            , True             , True                  , True                 ))
MyModalDef.Set08UseInDoesExists(Array As Boolean(False            , True             , False                 , False                ))
MyModalDef.Set09ComboQueries(   Array As String (""               , ""               , ""                    , ""                   ))
MyModalDef.Set10ComboLists(     Array As Map    (Null             , Null             , RankList              , Null                 ))
ABM.GenerateB4JCodeCRUDSheet(File.DirApp, "myCRUDCases", MyModalDef, ABM.MODALSHEET_SIZE_FULL)
A little bit of explanation on each line:

B4X:
' create a CRUD definition
Dim MyModalDef As ABMGeneratorCRUDDefinition

' IDFieldName: name of the ID field
' tableName: name of the table in your database
' title: title that will appear on top of the modal form
' saveButtonText: text on the SAVE button
' cancelButtonText: text on the CANCEL button

MyModalDef.Initialize("caseID", "tCases", "My Case", "Save", "Cancel")
' Array As String (real names in your database!)
' Very important! The order of the visible fields MUST be in the order they need To appear in the ModalSheet:
'
' Per row, Cells from left To right:
'
' e.g. |   field1   |  field2             |
'      |   field3                         |
'      |   field4   |  field5   | field6  |
'      |   field7                         |
'    
' Becomes: Array As String(notvisible1, notvisible2, field1, field2, field3, field4, field5, field6, field7)
MyModalDef.Set01FieldNames(     Array As String ("caseID"         , "caseSummary"    , "caseRank"            , "caseDescription"    ))

' Array As String, allowed formats:
'    R:O:S where R=Row, O=offset, S=size (Row starts from 1, All O+S in one row must add-up To 12!)
'    R:OS:OM:OL:SS:SM:SL where R=Row, OS=offsetSmall, OM=offsetMedium, OL=offsetLarge, SS=sizeSmall, SM=sizeMedium, SL=sizeLarge
'    Empty string If Not visible, e.g. an ID field
MyModalDef.Set02RowOffsetSizes( Array As String (""               , "1:0:9"          , "1:0:3"               , "2:0:12"             ))

' Array As String, labels on the component.
' Note: in Case of a switch the format Is:
'    "OnText,offText"
MyModalDef.Set03LabelTexts(     Array As String (""               , "Summary"        , "Rank"                , "Description"        ))

' Array As String, default value when the user creates a new record.
' Notes:
'    For Combos this must be the returnId!
'    For booleans this must be 'true' or 'false'
MyModalDef.Set04DefaultValues(  Array As String (""               , ""               , ""                    , "ret0"               ))

' Array as int, using CRUDTYPE constants
MyModalDef.Set05ComponentTypes( Array As Int    (ABM.CRUDTYPE_NONE, ABM.CRUDTYPE_TEXT, ABM.CRUDTYPE_COMBOLIST, ABM.CRUDTYPE_TEXTAREA))

' Array as boolean, used in the INSERT query
MyModalDef.Set06UseInInserts(   Array As Boolean(False            , True             , True                  , True                 ))

' Array as boolean, used in the UPDATE query
MyModalDef.Set07UseInUpdates(   Array As Boolean(False            , True             , True                  , True                 ))

'Array As Boolean, used in the Select query To check If a record already exists
' depending on the result, an insert of update query will be executed
MyModalDef.Set08UseInDoesExists(Array As Boolean(False            , True             , False                 , False                ))

' Array of String, combo query in format: Select returnId, TextToShowInCombo FROM Table WHERE your_where ORDER BY order
' where can contain variables that are other fields using '$', e.g. a combo that has other values depending on who was selected in the
' person combo.
'
' You have a combo prsId To pick a person:
'
' Select tPersons.prsID, tPersons.prsName
'    FROM tPersons
'    ORDER BY tPersons.prsName;
'
' You have a combo comId To pick a command And depends on who the person Is:
'
' Select tCommands.comId, tCommands.comName
'    FROM tCommands INNER JOIN tCommandsPersons ON tCommand.comId = tCommandPersons.comprsComId
'    WHERE tCommandPersons.comprsPrsId=$prsId$
'    ORDER BY tCommands.comName
'  
' The value of what Is in the prsId combo will be used in the query of the comId combo.
MyModalDef.Set09ComboQueries(   Array As String (""               , ""               , ""                    , ""                   ))

' Array of Maps, where key = returnId And value = TextToShowInCombo
' Use Null If Not applicable
MyModalDef.Set10ComboLists(     Array As Map    (Null             , Null             , RankList              , Null                 ))

' Will generate three files with B4J source code you can cut And paste.
' One with the code For the CRUD modal sheet, used in your page class
' One with shared helper methods you have To put in a module, called CRUD.
' One with shared database methods you have To put in a module, called DBM.
'
' Generating multiple CRUD sheets will create the same helper And database methods, so you only
' have To add them once in your code
ABM.GenerateB4JCodeCRUDSheet(File.DirApp, "myCRUDCases", MyModalDef, ABM.MODALSHEET_SIZE_FULL)
I think this system may save huge amounts of time writing WebApps in B4J with ABMaterial. Any thoughts?

Cheers,

Alwaysbusy
 

Harris

Well-Known Member
Licensed User
I think this system may save huge amounts of time writing WebApps in B4J with ABMaterial. Any thoughts?
I'm thinking you are Right! These look great!
You certainly have put a great deal of thought into this. I never would have imagined such a system.
Thanks
 

Harris

Well-Known Member
Licensed User
@alwaysbusy

B4X:
      Case "Vehicles"
        SQL_str = "SELECT Count(PK) as IDS FROM vehicle WHERE comp_id = "&Main.comp_id&" AND unit_type = "&veh_type
        SQL_Str2 =    "SELECT l1.PK, l1.unit_number, l1.vin, l1.notes, l2.Name FROM vehicle l1, insptype l2 WHERE l1.inspection_type = l2.PK AND l1.unit_type = "&veh_type&" AND l1.comp_id = "&Main.comp_id&" ORDER BY unit_number "&" LIMIT "& ((fromPage - 1) * iRecs) & ", "&iRecs
I do have additional conditions in my WHERE clause (comp_id and such) but I can easily over-ride the default after a paste.
This is easy (to modify) since I know what I am dealing with - whereas the generator has no idea. Hell, we have to do some work here at times!

Seems like the foundation will provide (at very least) 97 percent of code generation. The rest will be up to us to tweek (where needed).

Although I don't currently understand how you implement the quires, I shall wait to witness your final result.

Your Cell input for Modal sheets (where a row must be created with specs) is a bit perplexing.
I am guessing we define up front what each row number - and the cell layout will be.

Please, don't let this post distract you from your development efforts. I don't need or expect a reply at this time as it shall be revealed in your upcoming submissions.

(truly marvelous)

Thanks
 

alwaysbusy

Expert
Licensed User
@Harris Thanks for the input!

Just to clarify: a GenerateB4JCodeCRUDSheet() would only (well, actually, I think that is already a big part) generate the modal sheet part, not the table that presents all records.

e.g. in your example, you will still need to write the code for the 'page' part where you show all your vehicles (and use the multiple WHERE conditions). But I think I may assume at that time you have a way of uniquely identify each row in your table by an ID (I think PK in your case). It will generate all the code to create a new vehicle record in the vehicle table. You will be able to pass the PK id to the 'edit' button and to the 'delete' button.

So all the code (and queries) to open a modal sheet, where the user can enter the new data or edit the existing data of one vehicle, and when pressing save will either create a new vehicle record or update an existing one. And the code to delete a a record from the vehicle table. (if it needs to delete e.g. also the drivers of that truck, that part you will have to add in the generated code yourself.

On the cell part, I think this may the beautiful part as it will also generate lines like this for you (depending on what you wrote in Set02RowOffsetSizes():

MyModal.Content.AddRowsM(1, True,0,0, "").AddCellsOS(1, 0,0,0,9,9,9, "").AddCellsOS(1, 0,0,0,3,3,3, "")
MyModal.Content.AddRowsM(1, True,0,0, "").AddCells12(1, "")
MyModal.Content.BuildGrid

In short, for you vehicle program, you will need to write a ABMGeneratorCRUDDefinition for your vehicles, your employees, ...

Will it cover everything. No. e.g if you want the user to be able to set an image for the vehicle, you will need to modify the generated code to do so. This is way to complicated for a 'generator' to accomplish correctly by itself.

Maybe later we can have a 'GenerateB4JCodeTable' that can make such a paginated table, although I'm nof feeling hot on the idea as it will make all apps written in ABMaterial appear exactly the same and users should have a somewhat unique experience when they work with your app.

Already I think ABMGeneratorCRUDDefinition may need some extra info:

Set11ValidateInput() comes to mind and maybe some properties to personalize the 'Are you sure you want to delete..' or 'Please enter all fields...' messages.

So, the thought process is still a work in progress...

Cheers,

Alain
 

Harris

Well-Known Member
Licensed User
Just to clarify: a GenerateB4JCodeCRUDSheet() would only (well, actually, I think that is already a big part) generate the modal sheet part, not the table that presents all records.
Yes, I understand.
The table portion is actually quite easy and intuitive at present. Setting column headers, visibility, themes - adding data and controls to rows is a pleasant task. My BuildPage() and LoadTables() contains 8 different (but similar) cases... The modal sheets and save operations were the issue (time consuming) - even when I do copy and paste to create a new one. I have many more editors to create in my project and likely many more after that.
This will be great when you get it all laid out. Keep up up brilliant thought process.

I do wonder why other users are not chiming in with thoughts or suggestions? Quite likely because what you have defined requires no improvement?

Thanks
 

alwaysbusy

Expert
Licensed User
Some progress on the ABMGenerator for v1.07 I did tonight.

Writing this code (a big chunk was needed because I needed an ABMDateTimeScroller on my input sheet):

B4X:
Dim Generator as ABMGenerator
Generator.GenerateMessageBox(File.DirApp, "MakeNewToDo", "Een nieuw event aanmaken?", "Ja", "Nee", "")
 
Dim MyEventDef As ABMGeneratorCRUDDefinition
MyEventDef.Initialize("evID", "tEvent", "Vul alle velden van deze event in.", "Bewaren", "Annuleren", "Ja", "Nee", "Sluiten", "Ben je zeker dat je deze event wilt wissen?", "Gelieve eerst alle velden in te vullen!")
MyEventDef.DateTimeScroller.Mode = ABM.DATETIMESCROLLER_MODE_CLICKPICK
MyEventDef.DateTimeScroller.SQLSaveDateTimeFormat = "yyyy-MM-dd HH:mm:ss" 
MyEventDef.DateTimeScroller.TitleDateFormat = "DD"
MyEventDef.DateTimeScroller.ReturnDateFormat = "dd/mm/yy"
MyEventDef.DateTimeScroller.DateOrder = "ddMy"
MyEventDef.DateTimeScroller.DateMonthNames = "['Januari','Februari','Maart','April','Mei','Juni', 'July','Augustus','September','Oktober','November','December']"
MyEventDef.DateTimeScroller.DateMonthNamesShort = "['Jan', 'Feb', 'Maa', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec']"
MyEventDef.DateTimeScroller.DateDayNames = "['Zondag', 'Maandag', 'Dinsdag', 'Woensdag', 'Donderdag', 'Vrijdag', 'Zaterdag']"
MyEventDef.DateTimeScroller.DateDayNamesShort = "['Zon', 'Maa', 'Din', 'Woe', 'Don', 'Vri', 'Zat']"
MyEventDef.DateTimeScroller.DateMonthText = "Maand"
MyEventDef.DateTimeScroller.DateDayText = "Dag"
MyEventDef.DateTimeScroller.DateYearText = "Jaar"
MyEventDef.DateTimeScroller.PickText = "Kies"
MyEventDef.DateTimeScroller.CancelText = "Sluiten"
 
Dim cmbStatus As String = "SELECT evstatID, evstatOms FROM tEventStatus ORDER BY evstatOms"
Dim cmbType As String = "SELECT tEventType.evtypID, tEventType.evtypOms FROM tEventType INNER JOIN tEventType_Persoon ON tEventType.evtypID = tEventType_Persoon.evtypprsEvtypID WHERE (((tEventType_Persoon.evtypprsPrsID)=1)) ORDER BY tEventType.evtypOms"
Dim cmbTodoBy As String = "SELECT prsID, prsNaam FROM tPersoon ORDER BY prsNaam"
 
MyEventDef.Set01FieldNames(       Array As String ("evID"           , "evCreator"           , "evContact"    , "evDatum"            , "evStatus"       , "evType"        , "evToDoBy"          , "evToDoDatum"      , "evOnderwerp", "evAandacht"   , "evHot"        , "evCommentaar"   , "evAfsluitDatum"    ))
MyEventDef.Set02RowOffsetSizes(   Array As String (""               , ""                    , ""             , ""                   , "1:0:12"         , "2:0:12"        , "3:0:12"            , "4:0:12"           , "5:0:12"     , "6:0:6"        , "6:0:6"        , "7:0:12"         , ""                  ))
MyEventDef.Set03LabelTexts(       Array As String (""               , ""                    , ""             , ""                   , "Status"               , "Actie"         , "Uit te voeren door", "Uitvoer datum"    , "Onderwerp"  , "Aandacht"     , "Hot,"         , "Commentaar"     , ""                  ))
MyEventDef.Set04ComponentTypes(   Array As Int    (ABM.GEN_NONE     , ABM.GEN_NUMBER        , ABM.GEN_NUMBER , ABM.GEN_DATE_SCROLL  , ABM.GEN_COMBOSQL , ABM.GEN_COMBOSQL, ABM.GEN_COMBOSQL    , ABM.GEN_DATE_SCROLL, ABM.GEN_TEXT , ABM.GEN_NUMBER , ABM.GEN_SWITCH , ABM.GEN_TEXTAREA , ABM.GEN_DATE_SCROLL ))
MyEventDef.Set05DefaultValues(    Array As String (""               , "1"                   , "1"            , "NOW"                , "2"              , "1"             , "1"                 , "NOW"              , ""           , "0"            , "false"        , ""               , "NOW"               )) 
MyEventDef.Set06ComboQueries(     Array As String (""               , ""                    , ""             , ""                   , cmbStatus        , cmbType         , cmbTodoBy           , ""                 , ""           , ""             , ""             , ""               , ""                  ))
MyEventDef.Set08ValidationMethods(Array As String (""               , ""                    , ""             , ""                   , "NotMin1"        , "NotMin1"        , "NotMin1"           , ""                 , "NotEmpty"   , ""             , ""             , "NotEmpty"       , ""                  ))
MyEventDef.Set10UseInUpdates(     Array As Boolean(False            , False                 , False          , False                , True             , True            , True                , True               , True         , True           , True           , True             , False               ))
Generator.GenerateCRUDSheet(File.DirApp, "EventNotes", MyEventDef, ABM.MODALSHEET_SIZE_FULL)
Will generate about 700 lines of B4J code for you. This generated code is very optimized (e.g. check out how it solved the AddCells() methods!).

See the attachment for a PDF with all the generated code and in yellow what I needed to change for my particular app, but here is a snippit:



Alain
 

Attachments

Harris

Well-Known Member
Licensed User
B4X:
MyEventDef.Set07ComboLists(       Array As Map    (Null             , Null                  , Null           , Null                 , Null              , Null            , Null                , Null               , Null       ))
I need to create a static map for one of the combos..
What do I supply instead of Null?

The map will be:
item value list item
-------------------------------
A "1" "Warning"
B "2" "Speed"
-------------------------------

B4X:
Dim SQL_str As String = "SELECT pk, mastpk, name, speed, stype, s1, s2, comment, comp_id FROM  WHERE  = ? "
I see in the code gen we can define queries for combo items, but I don't see where we define the table names or where clause for the master data set used.
It creates field names in the select, but no from and where - since we didn't state this anywhere.
Above shows where we fill these in later...

B4X:
Sub GenCrudSheet
   
    Toast(" Building Crud Code",3000)
    Dim MyEventDef As ABMGeneratorCRUDDefinition   
   
MyEventDef.Set01FieldNames(       Array As String ("pk"             , "mastpk"              , "name"         , "speed"              , "stype"          , "s1"            , "s2"                , "comment"          , "comp_id"   ))
MyEventDef.Set02RowOffsetSizes(   Array As String ( ""              , "1:0:12"              , "2:0:12"       , "3:0:12"             , "4:0:12"         , "5:0:12"        , "6:0:6"             , "6:0:6"            , "7:0:12"    ))
MyEventDef.Set03LabelTexts(       Array As String (""               , "Master"              , "Zone Name"    , "Speed/Time"         , "Type"           , "Grace"         , "Spare"             , "Description"      , "Company"   ))
MyEventDef.Set04ComponentTypes(   Array As Int    (ABM.GEN_NONE     , ABM.GEN_NUMBER        , ABM.GEN_TEXT   , ABM.GEN_NUMBER       , ABM.GEN_COMBOLIST, ABM.GEN_NUMBER  , ABM.GEN_NUMBER      , ABM.GEN_TEXT       , ABM.GEN_NUMBER ))
MyEventDef.Set05DefaultValues(    Array As String (""               , "1"                   , "1"            , "1"                  , "1"              , "0"             , "0"                 , ""                 , "93"        ))
'MyEventDef.Set06ComboQueries(     Array As String (""               , ""                    , ""             , ""                   , cmbStatus        , cmbType         , cmbTodoBy           , ""                 , ""           , ""             , ""             , ""               , ""                  ))
MyEventDef.Set07ComboLists(       Array As Map    (Null             , Null                  , Null           , Null                 , Null              , Null            , Null                , Null               , Null       ))
'MyEventDef.Set08ValidationMethods(Array As String (""               , ""                    , ""             , ""                   , "NotMin1"        , "NotMin1"        , "NotMin1"           , ""                 , "NotEmpty"   , ""             , ""             , "NotEmpty"       , ""                  ))
MyEventDef.Set10UseInUpdates(     Array As Boolean(False            , True                 , True            , True                 , True              , True            , True                , True               , True       ))
gen.GenerateCRUDSheet(File.DirApp, "tiZones", MyEventDef, ABM.MODALSHEET_SIZE_FULL)   
   
End Sub
It seems that the "Set04ComponentTypes" doesn't provide an ABM.GEN_INTEGER type. The only time I see a created field type is when the result is from a map.
I have many INT type fields - which are now set as double.

Also, the associated DBM differs in structure from what I use with my previous project. I guess I could rename this one and use 2 DBM versions.

Attached is a copy of of the output file.
Thanks
 

Attachments

Harris

Well-Known Member
Licensed User
How sweet it is!!!!

Just a couple of items to set in place (table names, where clause, button labels and such) and away you go!

This saves HOURS of tedious coding by hand - where I would get it ALL wrong and angry...
The code is so clean! Man, hundreds of lines required from my 5 lines.... Freakin Amazing....

A couple of small issues (forgetting a SQLCLose, doubles instead of int's, etc) but otherwise spot on.

I banged off 3 editors on established grids in under 1 hour. Even (what seems) complicated relational stuff is made trivial.

Thank you, Thank you, Thank you.... Keep these GREAT features coming (whenever you find the time).

Harris
 

alwaysbusy

Expert
Licensed User
Great to hear @Harris! Could you post the issues you encountered in the feedback app? I'm about 2 weeks out of the next release so it would be nice to address them in 1.08. Thanks!
 

Harris

Well-Known Member
Licensed User
10-4 good buddy...

Hopefully some JasperSoft items will in next release. I sure would like to produce (call) reports from my webapp, rather than having them go to the JS server...
 

alwaysbusy

Expert
Licensed User
Hopefully some JasperSoft items will in next release. I sure would like to produce (call) reports from my webapp, rather than having them go to the JS server...
Could you elaborate what you would like more in it? Currently it should work without using the server. Mail me on this topic.
 

Harris

Well-Known Member
Licensed User
I added the file below that shows issues.
Look for:
************************************************************************
' issue...
************************************************************************
in the file.... not so many really.

Thanks
 

Attachments

Harris

Well-Known Member
Licensed User
After implementing 1.08, I don't see any fixes for the CRUD generator as described above. No prob, I know what they are and easily mod the generated code to resolve.
Quite understandable with all the other "wonderful" features added in 1.08. Looking forward to the JasperSoft which I shall beat up soon.

My bad for not adding this to the Feedback - your version control and bug reporting system.
I shall add it now with a link to above post that defines the issues.

I used it again today to create other modal sheets - what a time saver! I had to add some code to get other values but this was so easily accomplished. I sure admire your style of coding. It teaches me "the proper way".


Thanks
 
Last edited:

alwaysbusy

Expert
Licensed User
You are right. I completely forgot about these issues. :oops: Thanks for adding them to the feedback!
 
Last edited:

Harris

Well-Known Member
Licensed User
Hey, no problem... (I should have followed procedure - FEEDBACK)

Love what you have done with 1.08. Killing the selected grid item is a big plus. Now users, as I de-select, are not confused with which item is currently selected (when more than one grid - one to many) is present.

1.08 was real easy to migrate to. Thanks for that.

Looking at ABJasperSoft, I have questions which will be raised in a new thread. Need to explore before commenting.

Frankly, I still wonder why no one else has commented about the CRUD gen engine?

Do others love to waste time painstakingly writing this redundant code by hand? What's the deal?
(It is quite possible that all others know how to write efficient code without effort - I do not).

Maybe it is because this thread is buried here. No one is being notified.
Promote it upward as an important feature.???

As this goes, I should have PM'd you with this response since very few others will see this.

Thanks
 
Top