开发者

Cloning a PHP/MySQL database app (w/ some automation) in MS Access or OpenOffice.org Base

I wasn't sure whether to ask this here or on SuperUser, so I apologize if it doesn't belong here.

I created a small PHP/MySQL database app to manage the customer loyalty data for my mom's shop, intending to set it up locally on her cash register computer with XAMPP. However, I've been asked to reimplement the system in a GUI relational database such as MS Access or OpenOffice Base, primarily so that she can do things like mail merge and graphical reports with a GUI (that I don't have to write).

I can easily replicate my MySQL table structure and relationships, and create a few of the more basic forms and reports, but I've never done any scripting, macros etc in Access or Base. My PHP handled a lot more than just form input, there was some scripting involved that I don't know how to implement in Access / Base. Worth noting: if I end up using Access, it'll be Access 2007.

Here's a quick overview of what I'm trying to make, in case it helps. Sorry for the length.

The business is a take & bake food market, and the database is replacing a physical stamp-card loyalty system. Each customer gets a stamp on their card for every $25 they spend. They earn free meals as follows:

- On the 8th stamp, they earn a free side dish.

- On the 16th stamp, they earn a free regular size meal.

- On the 24th stamp, they earn a free family size meal, and their card resets to zero stamps.

The date of each stamp must be recorded (otherwise I'd just increment one field instead of having a stamps table).

I have 3 tables: customers, stamps, and freebies. customers has a 1-to-many relationship with both stamps and freebies.

  • customers is a simple contact list.

    columns: ID, firstname, lastname, email, phone

  • stamps keeps records of each stamp earned.

    columns: ID, customerID, date, index (1-24; the Nth stamp on that customer's card)

  • freebies keeps records of each free meal they have earned.

    columns: ID, customerID, date, size, is_redeemed

Here's the magic from my PHP that I don't know how to implement in Access/Base:

  1. When a user selects a customer and clicks an "add a stamp" button:

    • stamps is queried to grab the index from the last stamp for that customer => local variable N
    • if N == 24, set N = 0. Increment N by 1.
    • a record is inserted to stamps with the current date, customer id and an index of N
    • if N == 8, 16 or 24 a record is inserted into freebies with the ap开发者_如何学JAVApropriate size and an alert appears to notify the user that the customer earned some free shit.
  2. Some kind of "view customer" page (form? report?) that shows all the stamps and freebies they've earned, with "redeem" buttons next to the freebies that have not been redeemed.

In general I need to make it fairly idiot-proof and "big-button" -- automation wherever possible -- cashiers at the shop should be able to use it with no prior knowledge of databases.

Is this practical in a program like Access or Base, or should I just convince her to use my PHP version? If I need to write code, what language(s) do I need to teach myself? Should I be structuring my data differently? I'm not sure where to start here.


Really I think this would be a piece of cake. It's true like Tony said that you can continue to use the same tables/backend and that's probably the route I'd recommend. You'll need to install MySQL's ODBC drivers on any machine that will be linking to the MySQL database. After that create a DSN and then access the tables through that from within Access. You may want to add code later to relink the tables every time the software loads using DSN-less tables. This way the database can run on a machine that doesn't have a DSN configured. I do recommend that you go with either MySQL or SQL Server Express as opposed to an MS Access backend but I'm not going to take the time to elaborate on why.

I think you can actually get much more functionality from a traditional Windows Desktop Application (built in MS Access or VB.Net) than you could with PHP. And it's my own opinion that you'll be able to do it with less code and less time invested. I mentioned VB.Net but I'd probably recommend MS Access over VB.Net for databases although either one will do the job.

As Tony already mentioned, Access uses VBA language. It takes a little while to really pick it up unless you already have some experience with other programming languages that use the Basic syntax. I've found that moving from VBA/ASP to PHP/Javascript has been slow going though not necessarily so difficult. PHP uses the C style code with curly braces and VBA does not.

Coming from PHP, here's some things that may be new to you:

Stronger Variable Typing - In Access you can actually declare your variables with a specified data type such as String, Date, Integer, Long, Single, Double, etc. I recommend using this as much as possible. There are very few times when you will need to use the more general types such as Object or Variant. Variables declared with a specified data type will throw an error if you attempt to put the wrong data type into them. This helps you write better code, in my opinion.

Option Explicit - Option Explicit is a declaration you can put at the top of each code module to enforce that you have to declare a variable with a Dim statement before using it. I highly recommend that you do this. It will save you a lot of time troubleshooting problems.

Set MyVariable = Nothing - Cleaning up object variables after using them is one of the best practices of using MS Access. You'll use this to clean up DAO Recordset variables, ADO Connection variables, ADO Recordset variables, form variables, etc. Any variable that you declare as an object (or some specific type of object) should get cleaned up by setting it to Nothing when you no longer need to use the variable.

No Includes - There is no such thing as an Include statement in MS Access. You can import code modules from other Access databases. You can call functions contained in a DLL. But there is no include in Access like there is in PHP.

DoCmd - You'll have to use MS Access's DoCmd object to open forms and reports and perform other common tasks. Just a warning: it's frequently irrational. Long-time Access users don't think much of it but I've found these commands to have little cohesion or consistency. Let me give you an example. If you want to close a form you use this code: DoCmd.Close acForm, "frmSomeFormName" but if you want to open a form you use this code: DoCmd.OpenForm "frmName" In this example, why does opening a form get it's own OpenForm function while closing a form simply uses Close followed by a constant that tells Access you are wanting to close a form? I have no answer. DoCmd is full of this type of inconsistency. Blueclaw does a pretty good job of listing the most common DoCmd's although I don't think the examples there are exactly stellar.

References - You shouldn't need to use references very frequently. You will have to use them to enable things like DAO and ADO (see further down) or Microsoft Scripting Runtime (often used for accessing, reading, writing, etc. to files and folders). It's basically something you do once and then you forget about it.

ActiveX Controls - Probably better to try to build your project without using these. They require the same control to be installed on each computer that will run your software. I don't know much about it but I understand there are some compatibility issues that can come up if you use ActiveX controls in your project.

DAO - Data Access Objects - DAO is Access's original, native set of objects used to interface to your data container. Although it is primarily used to access date held in an Access database backend/container, it also can be used for some tasks when you are using ODBC linked tables. DAO is very helpful when you need to loop through recordsets to make changes in bulk. You can even use it to loop through form controls. One place I use this is to reorder line numbers in invoice details after a line gets deleted. Another typical use is to use it in "utility" functions where you need to change something in a given field or fields that can't be done with an update query.

CurrentDb.Execute("Update or Delete query here...") The Execute method of the CurrentDb object is, in my understanding, an implicit DAO call. It allows you to run Update or Delete queries on local and linked tables from VBA code. You can also achieve this using DoCmd.RunSQL but CurrentDb.Execute is the preferred method because it gives you improved error messages if something fails if you append ", dbFailOnError" as a second argument.

ADO - ActiveX Data Objects - I recommended not using ActiveX controls but this is one ActiveX technology you might need. To my knowledge, ADO is the only thing you can use to run stored procedures from Access. ADO is similar to DAO and was supposed to replace DAO although it didn't really. I tend to use both of them in my applications. It takes a while to figure out which one will do the job for you or which one will do it better. In general, I stick with DAO for everything except for running stored procedures or connecting to outside data sources (i.e. not using linked tables). DAO and ADO are both part of MDAC (Microsoft Data Access Components) which gets installed with MS Access.

File System Object - This object, mentioned above, is often used to access files and folders. You'll find you may have to use it to copy files, create text files, read text files, write to text files, etc. It's a part of Microsoft Scripting Runtime which is part of Windows Script Host (exists on all Windows computers although it can become "broken"). Access does give you some ways of access files and folders using VBA's built-in functions/methods such as Dir() but these functions don't cover all the bases.

SQL - Server's Query Language - You're probably familiar with SQL already but you'll need to get used to Access's "superset" of the SQL language. It's not drastically different but Access does allow you to use Access functions (e.g Len, Left, right) or your own custom functions. Your own functions just need to exist in a code module and be declared as public. An example of your own function would be Repeat (doesn't exist in MS Access, exists in MySQL) which is sometimes used to create indentation based on Count(*) in tables with child parent relationships. I'm giving that as an example although it's unlikely you'll need to use such a function unless you are going to be using the Nested Set Model to hold hierarchal categories.

Variables Cannot be in Literal Strings - This is a massive difference between Access and PHP. PHP lets you write: "SELECT * FROM tag WHERE tagtext = '$mytag'" In MS Access you'd have to write it like this: "SELECT * FROM tag WHERE tagtext = '" & strMyTag & "'" (You may not ever need to worry about this unless you are formatting a query in VBA to retrieve a DAO or ADO recordset. What I've just pointed out doesn't generally affect your form's or report's recordsource or saved queries because you generally don't use variables in those.)

Query - Not difficult to figure out but in Access a Query is basically a MySQL view. I actually don't save queries very often. I generally use them only to derive my SQL "code" and then I take that SQL and paste it into my form as the Recordsource instead of binding a form to a saved query. It doesn't matter which way you want to do it. There are pros and cons either way you choose to do this. As a side note, don't be afraid to create views in MySQL and link to them in Access. When you link to them Access sees them as tables. Whether or not it is updateable/writeable will depend on the construction of the view. Certain types of queries/views (such as unions) are read-only.

As a final note, I recommend MS Access over OpenOffice.org Base. I tried out Base a couple years ago and I found it to lack so many features. However, I was already experienced in MS Access so I'm not sure that I gave OpenOffice Base a fair trial. What I found missing was events. I'm accustomed to being able to fine-tune my forms in MS Access to give users a very responsive UI with lots of feedback and I couldn't figure out how to do this in Base. Maybe things have changed since since I last tried it, I don't know. Here's an article comparing Base to MS access.

Other SO Access gurus, feel free to point out any errors in my answer. I still consider myself a rookie in programming.


I can't speak for Base. However Access can link to the MySQL database directly so you don't have to redo the data. As far as creating the bits and pieces of code in Access that would be quite easy. Access, Word and Excel, use VBA which is identical, except for Access, Word or Excel object model specific stuff, to Visual Basic 6.0. Indeed a minor obscure bug when using the VBA editor is also present in the VB6 editor.

I will also add that one of my Access databases had 160 tables, 1200 queries, 350 forms, 450 reports and 70K lines of code. So your app is quite small by comparision.

On the freebies table I would change the is_redeemed field to a date_redeemed. I definitely agree with recording each stamp and and freebie earned as separate records in tables. Thss way it's real easy to show the customer a history rather than just stating you've only got x stamps.

Also consider a bar code reader and issueing the users bar coded plastic wallet cards. This will greatly speed up the time required by the clerk to look up their records. Indeed consider using common to your area loyalty cards they might already have such as a Safeway or AirMiles card. I'd put that number in a separate table though just in case they lose the first card they were given. Or so they can track multiple cards. A family might want want to accumulate points onto one account.

Thanks for the lenghty posting. This enables us to give you some suggestions on different facets you might not have thought of in the first place.


My suggestion: don't do it. Run a mysql server on the PC in question, have your PHP app as the front end for the cashiers, and then if you want MS Access's reports feature, just have Access connect to the mysql database with ODBC.

The best implementation is quite frequently the one you already have.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜