Gary
Members-
Content Count
137 -
Joined
-
Last visited
Everything posted by Gary
-
@Columbo My 2 cents: Beautiful UI BTW. I don't like to do anything in a form's OnCreate event that I don't have to, it has caused me trouble in the past as things may not always be created before I use them. Nor do I ever open Databases there, use the OnShow if you must, even better have a dedicated button. Break things down into separate procedures and assign them to events. I added a combobox for the search and implemented the search with a simple RecNo assignment. Things I changed it the Object inspector: Form WindowState = wsNormal Position = poScreenCenter CustomTitleBar = False // You cannot move it around or Min Max with this set true ComboBox DropDownCount = 15 //However many you want unit Dinobase_u; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Imaging.jpeg, Vcl.ExtCtrls, Vcl.StdCtrls, Vcl.ComCtrls, System.ImageList, Vcl.ImgList, FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Error, FireDAC.UI.Intf, FireDAC.Phys.Intf, FireDAC.Stan.Def, FireDAC.Stan.Pool, FireDAC.Stan.Async, FireDAC.Phys, FireDAC.Phys.SQLite, FireDAC.Phys.SQLiteDef, FireDAC.Stan.ExprFuncs, FireDAC.Phys.SQLiteWrapper.Stat, FireDAC.VCLUI.Wait, FireDAC.Stan.Param, FireDAC.DatS, FireDAC.DApt.Intf, FireDAC.DApt, FireDAC.Comp.Client, Data.DB, FireDAC.Comp.DataSet, Vcl.DBCtrls, Vcl.Mask, Vcl.Buttons; type TfrmDino = class(TForm) pnlTitlebar: TPanel; Image1: TImage; pnlHeader: TPanel; Image2: TImage; lblName: TLabel; lblMeaning: TLabel; lblPronounce: TLabel; lblPeriod: TLabel; lblMainGroup: TLabel; pnlFooter: TPanel; Footer: TImage; lblSize: TLabel; lblLived: TLabel; lblDiet: TLabel; lblFossils: TLabel; PLTabSheet: TPageControl; TabSheet1: TTabSheet; SizeComp: TTabSheet; dinoImage: TImage; dinoSize: TImage; conPLife: TFDConnection; tblPLife: TFDTable; Datasource1: TDataSource; lblRecno: TLabel; btnExit: TBitBtn; dbeName: TDBEdit; dbeMeaning: TDBEdit; dbePronounciation: TDBEdit; dbePeriod: TDBEdit; dbeMainGroup: TDBEdit; dbeSize: TDBEdit; dbeLived: TDBEdit; dbeDiet: TDBEdit; dbeFossils: TDBEdit; dbmFactfile: TDBMemo; dbeRecno: TDBEdit; DBNavigator1: TDBNavigator; cbxSearch: TComboBox; procedure btnExitClick(Sender: TObject); procedure cbxSearchClick(Sender: TObject); procedure FormShow(Sender: TObject); procedure tblPLifeAfterScroll(DataSet: TDataSet); private { Private declarations } procedure OpenConnection; procedure OpenTable; procedure LoadList; procedure LoadImages; public { Public declarations } end; var frmDino: TfrmDino; implementation {$R *.dfm} uses System.IOUtils, VCL.Dialogs; const DINO_DB = 'dino.db'; procedure TfrmDino.btnExitClick(Sender: TObject); //Exit Button begin Close; end; procedure TfrmDino.cbxSearchClick(Sender: TObject); begin //Search... is at ItemIndex[0] and we load the list from the table so //a 1 for 1 on the count so nop searching needs to be done just //set the Tables RecNo it is write as well as read property tblPLife.RecNo := cbxSearch.ItemIndex; //Set combobox back to Search... cbxSearch.ItemIndex := 0; //if you do not like the search box selected set focus to any control dbeName.SetFocus; end; procedure TfrmDino.FormShow(Sender: TObject); begin OpenConnection; OpenTable; LoadList; //Images will be loaded when record changes after this LoadImages; end; procedure TfrmDino.LoadImages; var lName : String; begin lName := tblPLife.FieldByName('name').AsString; // Load the dino image and display it dinoImage.Picture.LoadFromFile('dino_images\' + lName + '.jpg'); // Load the size image and display it dinoSize.Picture.LoadFromFile('dino_size\' + lName + '_size' + '.jpg'); end; procedure TfrmDino.LoadList; begin cbxSearch.Items.Clear; cbxSearch.Items.Add('Search...'); //Disable all data aware controls so the UI does not repaint //as we load the list tblPLife.DisableControls; try tblPLife.First; while not tblPLife.Eof do begin cbxSearch.Items.Add(tblPLife.FieldByName('name').AsString); tblPLife.Next; end; finally tblPLife.First; tblPLife.EnableControls; end; end; procedure TfrmDino.OpenConnection; begin conPLife.Params.Database := ExtractFilePath(Application.ExeName) + DINO_DB; try conPLife.Connected := True; Except on E: EDatabaseError do begin ShowMessage('Error connecting to: ' + conPLife.Params.Database + ': ' + E.Message); end; end; end; procedure TfrmDino.OpenTable; begin try tblPLife.Open Except on E: EDatabaseError do begin ShowMessage('Error opening table with: ' + E.Message); end; end; end; procedure TfrmDino.tblPLifeAfterScroll(DataSet: TDataSet); begin //if Controls are disabled we are loading the list and don't want //to load images if not tblPLife.ControlsDisabled then LoadImages; end; end.
-
I was able to get it. However it will throws an error when trying to open database. The database opens in DB Browser so it's a valid database. You should include the project files.
-
I think JonRobertson has identified the problem. In his post he recommends you use one dataset and one datasource. Do you have multiple dataset's? If you are still using the FDQuery with parameters, as well as a table that could be the problem. They have different use cases and mixing them will cause you frustration! The Parameterized query will only ever return one record. You cannot use a DBNavigator since there is only one record, there is no prior or next record, the one record is the first as well as the last. This is fine for searching a table. When your user presses the search button you can update your query from the edit and load the data as well as your images. However, with an interface like this how will your users see any other entries unless they know, and as you mentioned can spell the name they are looking for? You cannot navigate your database table with a parameterized query. If you managed to get this working with the query you have much more going on. For what you want you should use a Table or "Select *" in your query. Now your dataset will have all the records from the table and you can hook up a DBNavigator. As you use the buttons to move from one record to another the Dataset's (Table or Query since they both descend from TDataset) AfterScroll event will be fired, you can load your images or any other custom data display you have here. To search for a particular record, you use the Locate method of the dataset passing the value from your search edit. if not DataSetName.Locate('name', Edit.Text, [loCaseInsensitive]); then ShowMessage(Edit.Text + ' not found.'); Locate returns true or false so you can check it. If successful the dataset will move to the record, your data aware controls will display the data and the Dataset's AfterScroll event will be called and the images will be loaded. You should post your code with your questions, at least the procedure you are working on.
-
Yes, I would like to see the data. As Stano said, there is another way to accomplish your objective, always is in Delphi. Using the Query is always better in a Client/Server environment. In your use case your data is local and I don't think with the small amount of data the performance would suffer. It is muck easier in this case to use DB controls and a Table. No SQL at all. You use the Locate method of the DataSet to search for specific items, and that allows you to hook up the navigator and just scroll through the table.
-
How is all working fine different than compiled?
-
Couple of things to check. Is the dbEdit field set properly? Are you still using the parameterized query? If so there will only be one record in your dataset, so no records for the navigator to move to, in fact if you are using the parameterized query the navigator is pointless it only works on a set of records.
-
Use the DataSource DataChange event, (Object Inspector Event tab) put your image loading procedure there. It will be called every time the record changes. Not sure how you get the record number into the edit as it's not a field? You can add code to update a label in the DataChange event also, Label.Caption :='Record Number: " + Query.RecNo.ToString. If you want to get fancy with the names you can try iterating through the records and filling a comboBox with the names. Then use it's on change event to trigger your lookup. Your users will just select from a list (Have fun researching that 🙂 ).
-
I just got all cross platforms working the other day. XCode had an update today and I think the Simulator was updated to 17.2? Anyway now I can no longer deploy to it. PAServer is working as I can still deploy to MacOS. Anyone else have same problem? Both versions Delphi 11.3 Windows 11 Delphi 12 Windows 11 Virtualbox [PAClient Error] Error: E6664 /Users/sheltons/PAServer/scratch-dir/gshel-MacMini/Project1.launchscreen/Assets: error: The operation couldn’t be completed. Failed to locate any simulator runtime matching options: {[PAClient Error] Error: E6664 BuildVersionString = 21C52; [PAClient Error] Error: E6664 Platforms = ( [PAClient Error] Error: E6664 "com.apple.platform.iphonesimulator" [PAClient Error] Error: E6664 ); [PAClient Error] Error: E6664 VersionString = "17.2"; [PAClient Error] Error: E6664 } [PAClient Error] Error: E6664 Failure Reason: Failed to locate any simulator runtime matching options: { [PAClient Error] Error: E6664 BuildVersionString = 21C52; [PAClient Error] Error: E6664 Platforms = ( [PAClient Error] Error: E6664 "com.apple.platform.iphonesimulator" [PAClient Error] Error: E6664 ); [PAClient Error] Error: E6664 VersionString = "17.2"; [PAClient Error] Error: E6664 }
-
@Dave Nottage That did it. Thanks a million! Glad I started here. Not sure what I think of this Mobil development, IDE seems so fragile.
-
@Columbo FWIW Listen to Remy! He's been around for a while, even part of the old Team 'B' I believe. He's one of the few experienced programmers that actually help newbies, and that takes patience. He helped me some time ago with some Interbase deployment issues that looking back were so simple yet at the time I just couldn't get it. Weirdo12 seems to be experienced with Database's especially Firebird, FireDac and Zeos so read his posts closely as well. I've learned a lot just reading them 🙂 The Database landscape has changed drastically since DBase and the Borland Database Engine. Everything is in the cloud, 3 Tier and Rest and it is good to embrace this change for Enterprise applications, but for the kind of Home and friend use that you and I do, Delphi offers much simpler 2 Tier or even direct access solutions. For example, you can use a DBEdit instead of a plain edit and connect it to the "Name" field in your Query and never have to worry about 'Loading data' into controls. There are several Data Aware controls that you just set their DataSource, or additionally a particular field and the data just display's. You can right click on the TFDQuery in your designed and if you have your connection active you can use the 'Parameters' tab to set a value and see the result at design time, and more.. Much of what you are doing looks like a console application. Everything is Visual now. Like Remy said set up your UI in the Object inspector, look for properties, there is a WindowState property set it in the designer to wsMaximized not in code (Check out the Position property of the form). In the last projects you posted what you are trying to do can be done in the designer and only 1 or 2 lines of actual code. While that may not sound exciting if you want to write code, you can whip out a simple Home use DB application that way in a matter of minutes, very exciting! BTW online help for Delphi 11 can be found here: https://docwiki.embarcadero.com/RADStudio/Alexandria/en/Main_Page
-
@Columbo Glad you did not give up! The control that is selected (Focused) when your app runs is determined by it's TabOrder. You can see this as a property in the Object Inspector. To reorder them you can change them manually or right click the edit box and select TabOrder... to arrange all components.
-
I would agree with Stano! However, this means you need to install 3rd party packages. You will need Data Access components. Zeos is popular. You will need to install and learn Firebird. Firebird and Interbase have the same roots. They were forked from same source some time ago. Embarcadero continues to develop it as commercial software, even if the community edition lets you build with IBLite, you will need to pay a license to use it outside the IDE. Firebird.org continues on the open source version. I believe they just released version 5? I did some projects with Firebird. They still work, but I personally find it difficult to work with. No doubt it is my lack of experience. I'm sure there is freeware that can at least export your old data to a .csv file, then as Stano said you can use FireDac BatchMove component to import into your Database of choice. I just added this feature to the one and only commercial app I have. It downloads GPS data in .csv format from the company's vehicle tracking service and imports it into a MYSQL Database.
-
What version of Delphi are you using? I have Pro + Devart Data Access components. Pro edition supports SQLite & Interbase Lite with Firedac out of the box, but not client/server (MySQL, Oracle..), not sure if the community edition supports any Databases. If you are using a trial edition Database support will end. If community edition supports SQLite I wouldn't discount it so fast, especially if you want to do any mobile apps. I'm trying to decide to use it or IBLite that comes with Pro on my next app since I want to support mobile. You can use Devart UniDac (commercial), or Zeos Database components (Open Source) for Database access with the community edition as long as your not making >5K annually from it. Both allow you to connect to many Databases. Firebird is a favorite of many Delphi developers, and has a client/server but also what is considered an embedded version. You just distribute a few files with your exe. This works well for small hobbyist apps. Firebird is actively supported. I used it in my last 2 small apps that will run from a USB drive. Another option is an older Database, "Advantage". SAP discontinued support a few years back at version 12, but the source is still available. It allowed you to use the local (embedded) version with up to 5 users before having to purchase the client/server version. It only works on Windows, but you just deploy 2 dll's minimum. The good thing with it is it has it's own data access components, just like the FD ones you just used. It has it's own GUI for creating and testing your databases. I just installed it on Delphi 12 and it still works just fine.
-
@JonRobertson That's great. I didn't see where he uploaded his database. Did you create it from his image?
-
@ColumboYour 2 hours ahead I'm in California You definitely need to figure out the SQL. If the tool you use doesn't let you test SQL statements, try DB Browser for SQLite (sqlitebrowser.org) Free/Donate. Now that you know it works with the table, you can try experimenting in the FDQuery editor. Right click FDQuery select Query Editor, enter your SQL and press Execute. The Delphi sample data retrieves the employees table with any of these 3 statements: SELECT * FROM employees SELECT * FROM 'employees' SELECT * FROM 'employees'; Can't help but think your table name being all uppercase is the problem. Try putting it in single quotes like above. I don't use SQLite so maybe someone else knows the problem for sure. Cool thing about Delphi is there is always "more than one way to skin a cat". In the Object Inspector for the Table set the Filter property to hyear = '1942', you only need the quotes around 1942 if it's a string, if the field is a number their are not needed, and the Filtered property to true.
-
Now use your original code to populate the memo, just use the Table
-
If the Active property is checked as true your good!!! You can try hooking up a DBGrid just to give yourself an extra boost. Drop a TDataSource on the form, set it's DataSet property to your table. Now a DBGrid and set it's DataSource property to the DataSource. If the Table is active you'll see the data
-
Some like to always use a Query, but if your just doing a SELECT *, a table component is way easier. You just set the connection and TableName properties, no need for a SQL Statement at all.
-
The tool in your previous post showing the table in the Database. Try the FDTable first
-
You can also try adding a FDTable instead of a FDQuery. Drop it on the form, make sure it's connection property is set to your connection, make sure the connection is set to connected. With the FDTable selected, In the object inspector look for the TableName property. There will be a dropdown listing all tables in the DataBase. Select your table, then set the FDTable Active property to true. If no errors you are connected
-
Problem in your SELECT statement. Did you enter it without any quotes ? Just SELECT * FROM DAT2 ? Can you get the same query to work in your Database tool?
-
Yahoo! So no problem connecting. Now on to the Query. Make sure the connection property of the FDQuery Component is set to your connection then right click and select Query editor, enter your SQL statement. See my previous image. Then click Execute. What happens?
-
What happens when you press "Test"?
-
BTW this is all in the designer you don't need to even run the program to get it working