476

(37 replies, posted in General)

Adam,
Your number 2 in your post was put in the last project. I added the feature to insert the next recurring expense when saving. Since you use dates mostly in the dd/mm//yyyy, for the sake of testing the new feature use the attached project. You were getting errors in Recurring expenses 5.zip probably because it was converting dates to mm/dd/yyyy.


Dimitry,

For Adam (Ad1408) number 1 in his last post, is there a way to extract dates from a dataset "AsDate"? I had to extract the date AsString to retrieve a date and then manipulate into a format where I could add days, months, etc. However, I always convert to the format mm/dd/yyyy so it's not an issue for me, but others may use the format of dd/mm/yyyy. The attached project should work for him because he uses the dd/mm/yyyy format.  Is there a way to write the following (line 120 in the script of the attached project) so that it goes directly into a date variable so that the date can be incremented.

String_Date := ExpResults.FieldByName('Date(recurDate)').AsString;

477

(37 replies, posted in General)

Adam,  Maybe the attached is a little closer. On initially entering in an expense that is recurring, the system will generate the next recurrence of the expense when saving and show on the grid. From then on, the other process (App Start process) will take over from there to generate the remaining recurring expenses as they are to occur.

The reason for the manually generating the date format in the bulk processing of recurring expenses is because I could not extract the date from the dataset as a date for MVD to recognize. I had to extract it as a string and manipulate it to a date format in order to add days, weeks, months... to it. Maybe Dimitry could assist with this. Here is the line in the project that I was having trouble extracting as a date so instead I used "AsString".

ExpResults.FieldByName('Date(recurDate)').AsString;

478

(37 replies, posted in General)

It only creates new recurring expenses at application startup.


If you changed your date format to MM/DD/YYYY then just go back to Recurring Expenses 3.zip and use that project.

479

(37 replies, posted in General)

Thanks for the screenshot Adam. I think maybe it did not work because it looks like your date fields are DD/MM/YYYY where I have it as MM/DD/YYYY. So I made a small change in my script to reverse the day and month. See if the attached corrects the situation.

480

(37 replies, posted in General)

Hmmm....Not sure what's going on. How far back did you make the date for the daily expense recurrence. If you go back years, it will create an expense record for each day from that date forward till tomorrow. And if you do that for multiple expenses it will take some time to insert/update records before the app shows the first form. I tested a single daily recurrence and went back a full year, which is highly unlikely in real life.  It took maybe 20 seconds or so before the first form shows, but it did not crash or anything like that. And the app restarted fine. Try emptying your database and start fresh again.

481

(37 replies, posted in General)

Ok Adam, I think I have put together something that I think you are looking for. I took out all the Paid stuff and put it back to what you had prior. Now the application, upon startup, will check to see if the Recur Date on all recurring expenses has arrived and if it has the appication will create the next expense record at that time. It will turnoff the recurring flag of the original so that it will not create a duplicate expense the next time you start the application.


If you accidentally delete the latest recurring expense, you can go back to the prior expense in the series and turn on the recurring checkbox and set the recurring value combobox and you are all set. The app will re-create the recurring expense the next time you startup.


I did not use the Recur Time. I don't think it's necessary. I don't think there are hourly expenses that you have to check each hour.


Hopefully this is closer to what you want. I'm not in a position where I can spend a lot of time on this, but I'll help you as much as I can. If others have any other ideas on this, they should chime in. I'm certainly not professing that my way is the only way.

482

(37 replies, posted in General)

It looks like you are getting the error when you are adding an expense simultaneous to paying it, which is fine. The qty appears to be empty which is causing the error.  I would assume this should never be the case, but to fix this particular situation you can set the default value to 0 for Qty on your Expense form

https://s10.postimg.org/ptvvg9dc9/Qty_Default.jpgimage host

483

(37 replies, posted in General)

Not sure why you are getting a script error. I don't, no matter what entry is selected in the combobox. I did not use the recurring date and time, so it does not matter whether they are checked or not.

484

(37 replies, posted in General)

That might work for the first time of the expense, but it still does not answer when to create the next expense. I didn't want to leave you hanging so I incorporated the trigger based on an expense being paid. In the attached project, there is a button called Paid. Upon clicking this button the expense will be identified as Paid and if it is a recurring expense then the next expense record will automatically be created. The date of the next expense is based on the recurring every... combobox.  Hopefully this will help set you in the direction you want.

485

(37 replies, posted in General)

Adam,
Before a script can be developed, there needs to be a design question answered. Something needs to trigger the creation of a new expense record for a recurring expense. What is that trigger? It needs to be a button click or some sort of event (such as when an expense is paid or something) to cause the next expense record creation for a recurring expense. This needs to be answered first.

486

(6 replies, posted in General)

Change the cancel button code to the following.


procedure frmStudent_btnCancel_OnClick (Sender: string; var Cancel: boolean);
begin
    End_Data := Load_Record_String(frmStudent);
    If Start_Data <> End_Data then
      Begin
        If MessageBox('Changes were made to the data on this form.'+#13#10#13#10+ 'Are you sure you want to cancel changes?','Confirm',MB_YESNO+MB_ICONQUESTION) = IDYES then
          Begin
             if frmStudent.dbAction = 'NewRecord' then
              begin
               SQLExecute('DELETE FROM checks WHERE id_Student='+IntToStr(frmStudent.btnSave.dbGeneralTableId));
               SQLExecute('DELETE FROM student WHERE id='+IntToStr(frmStudent.btnSave.dbGeneralTableId));
              end;
              frmStudent.Close
          End else
          Begin
          frmStudent.btnSave.SetFocus;
          Cancel := True;
          Exit;
          End;
      End;
end;

Also, I noticed you changed the name of the cancel button so you need to use the On_click procedure name above.


One more thing. The method of comparing changes I showed you will work for all top level forms (such as frmStudent in your case), but if you have a lower level form (a child form such as frmCheck in your case) off of the main form and you want to use the same methodology for checking at cancel time, then you will need to define separate global variables for the lower level form (something like Chk_Start_Data and Chk_End_Data) and change the names in the cancel button procedure.

487

(6 replies, posted in General)

Try this

procedure frmStudent_btnCancel_OnClick (Sender: string; var Cancel: boolean);
begin
  if (frmStudent.dbAction = 'NewRecord') then
    begin
      SQLExecute('DELETE FROM checks WHERE id_Student='+IntToStr(frmStudent.btnSave.dbGeneralTableId));
      SQLExecute('DELETE FROM student WHERE id='+IntToStr(frmStudent.btnSave.dbGeneralTableId));
    end;
end;

488

(2 replies, posted in General)

Adam, See if the attached is what you are looking for. The method to my madness is to load all the fields on a form into one string. I created a function to do this. You then call this function at the On_Show event of any form and hold the result into the Start_Data string varialble. You then call the function again on the On_Click event of the Cancel button and hold the data in the End_Data string. You just compare the two strings on the Cancel button event and produce a message if they do not compare equally.


This method will not handle images stored in the database. You will need to handle images separately by holding the image at the start of the form and then check it when you click the Cancel button.

489

(11 replies, posted in Script)

Gonpublic & Derek,
Derek was spot on. I made a slight mod. Derek's picture may not have shown up on your form because it was located on his computer. I made an image folder within the project and placed a picture there to show you the results.

490

(11 replies, posted in Script)

Here is an example. See attached.

491

(6 replies, posted in General)

You can also do the following without using script. In the Objector Inspector for the combobox, you can use the filter property to sort the combobox.


https://s7.postimg.org/ybgdqgst7/Sort_Combo_Box_Desc.png

492

(48 replies, posted in General)

No problem Adam.  Actually I learned something new in putting this together for you. You can declare global report variables in FastReport Code tab. These variables can be used/manipulated and printed anywhere in the report. A good example of this would be when you want to repeat or use group header data in a group footer.

493

(48 replies, posted in General)

Adam, See attached for fix. You do not need the three extra fields you defined in the SaleInv table. I used the fields already defined in that table for the report.

494

(5 replies, posted in General)

Not sure if this answers your question. But there isn't anything that MVD does automatically to upgrade database tables for users. What I do is create a separate MVD program. The only thing this MVD program does is run a script similar to the following:

SqlExecute('ALTER TABLE MyTable RENAME TO TempTable');
    SqlExecute('CREATE TABLE MyTable ('
      + 'id               INTEGER PRIMARY KEY ASC,'
      + 'Field1    TEXT,'
      + 'Field2    TEXT,'
      + 'Field3    TEXT,'
      + 'NewField  TEXT)');

    SqlExecute('INSERT INTO MyTable ('
                            + 'id,'
                            + 'Field1,'
                            + 'Field2,'
                            + 'Field3) '
                        + 'SELECT id,'
                            + 'Field1,'
                            + 'Field2,'
                            + 'Field3 '
                    + 'FROM TempTable');
    SqlExecute('DROP TABLE TempTable');

I use a third party install software to install the upgraded MVD application (without the database). The same install process then installs and runs the MVD database table upgrade program (script above). After the installation the database table upgrade MVD program is deleted because it's not needed any longer. One thing you have to pay attention to is making sure that the "server" setting in the settings.ini file in the database upgrade folder is pointing to the installed application database. My install process does this automatically so the user does not need to do anything. The whole thing is pretty seamless from my standpoint. Hope this helps.

495

(22 replies, posted in General)

Project fixed

496

(22 replies, posted in General)

Adam, when you copied Dimitry's code from Groups you missed replacing a variable in the following line:

frmInvoice.cbCustomer.Text := s_cbGroups;

It should be

frmInvoice.cbCustomer.Text := s_cbCustomer;

497

(13 replies, posted in General)

Dimitry,

Was wondering. Did you remove the quotes in the LAST_INSERT_ID('') statement in 3.2? I was recompiling apps and discovered that having the quotes inside the parentheses produces an error now. I removed the quotes and the error went away. It's no problem. I was just curious.  Thank you.

498

(22 replies, posted in General)

Adam, your combobox filter needs to include the first name. Replace your frmInvoice.cbCustomer.dbFilter with the following:

frmInvoice.cbCustomer.dbFilter := '(lastName LIKE ''%'+ s_cbCustomer +'%'''+') or (firstName LIKE ''%'+ s_cbCustomer +'%'''+')';

499

(4 replies, posted in Reports)

Welcome to MVD.


I learned the technique in the attached from Dimitry in this forum. I know sometimes it is difficult to find things on the forum because the solutions are not always under the keywords you think they should be. I usually will download solutions as they are presented even if I don't need it immediately. This way I have a local reference that I can find easier in the future when I do need it.

In the attached project pay attention to the design mode and preview mode in the script. You have to control which mode you want within the script. Hope this solution is what you are looking for.

500

(2 replies, posted in General)

For header alignment:

Form1.GridEmployees.Columns[k].Header.Alignment := taRightJustify