July 2nd, 2008
In a tragic episode of miscommunication and server migration, I have managed to loose my once beloved Wordpress Blog (http://enja.org/david). I did, however, by the magic of the Wayback Machine uncover an archive from 2007. All of the important posts are there (the AJAX articles) and the other diatribe remains as well.
http://web.archive.org/web/20070105031325rn_1/www.enja.org/david/
Mad props to Archive.org.
-David
Tags: archive, nostalgia
Posted in General, archives | No Comments »
July 2nd, 2008
Author’s Note:
Here is another article from my long lost blog. Ajaxian still links in here, as well as many other personal blogs. See my previous post for background.
-David
Post:
In light of the comments on the original post, i thought it would be nice to reiterate some other people’s workarounds.
This was the first one brought to my attention, and actually is how i work around the caching these days. Basically, you add a superfluous variable to your string of GET vars that is unique - timestamp works fine. I actually go a little bit further and use milliseconds since the app i’m working on makes several requests per second.
servlet/imagemaker.jsp?foo=bar&goo=car
Change to:
servlet/imagemaker.jsp?foo=bar&goo=car&time=111111111
Here is function to uncache the url:
function uncache(url){
var d = new Date();
var time = d.getTime();
return url + ‘&time=’+time;
}
This workaround looks like as close to a valid solution as there is. It simply adds an arbitrary variable to the POST vars (sent in the send method).
http.open(’post’, ‘myfile.php’);
http.setRequestHeader(’Content-Type’, ‘application/x-www-form-urlencoded’);
http.onreadystatechange = handleResponse;
http.send(’var=1′);
A null or empty string for the send method will cause IE to cache.
My only recommendation for that second solution would be to change the POST var to send(’ie=teh_suck’);
Kudos to contributors.
Comment Thread:
- Sujai Said…
-
What about xml files. I am trying to call xml using ajax. I tried POST its not working
- Steve Said…
-
Thanks for this, I had already spent far too long trying to work out why ie was caching the records (thought it may have been a bug in ie7). For those that are interested below is a script i used the above suggestion with, it uses a php loop to change the field which it will output the fetched data to.
cheers
function getContent(){
var page=’./query.php’;
var selected=document.getElementById(’selected’).value;
if (selected==’’){selected=’none’;}
//params has to have following format
//i.e.: c=1&id=3….
//Clear our fetching variable
var xmlhttp=false;
//Try to create active x object
try {
xmlhttp = new ActiveXObject(’Msxml2.XMLHTTP’);
} catch (e) {
try {
xmlhttp = new ActiveXObject(’Microsoft.XMLHTTP’);
} catch (E) {
xmlhttp = false;
}
}
if (!xmlhttp && typeof XMLHttpRequest!=’undefined’) {
alert(’Error’);
}
var rowNum=’’;
xmlhttp.onreadystatechange = function(){
if(xmlhttp.readyState==4 && xmlhttp.status== 200) {
document.getElementById(’qty’).innerHTML = xmlhttp.responseText;
}
}
params=’selected=’+ selected +’&rownum=’+ rowNum +’&rnd=’+ Math.random()*99999;
xmlhttp.open(’POST’, ‘./query.php’, false);
xmlhttp.setRequestHeader(’Content-type’, ‘application/x-www-form-urlencoded’);
xmlhttp.send(params);
}
- Chris Said…
-
Glad I have found this article, bookmarking for work =D
We plan on doing an entirely new website (hopefully I can get them to separate html/css/back-end) this time around as well as get some ajax in there to make life a bit easier!
- Mark Said…
-
Excellent. Thanks for this.
Been banging our heads against the proverbial Brick 2.0 Walls trying to work out why our Ajax looping updates don’t update in IE7.
- Gareth Said…
-
That worked a treat.
I’m still a bit annoyed that I have to do this for every request. Such is the life we lead.
- Gene Said…
-
Wow, thank you VERY much. I’ve been having this problem for some time now. This little line “req.send(’var=1′);” really helped me out. Thanks VERY VERY much.
Tags: ajax, archive, ie, internet, javascript, xmlhttp
Posted in archives | No Comments »
July 1st, 2008
Author’s Note:
I wrote this article on January 13th, 2006. Clearly, a lot has been accomplished and discovered on the AJAX front. We now have “wonderful” frameworks and libraries that handle all of the connection stuff automatically, totally cross-browser. I’m reposting this for my own personal nostalgia, as well as to keep the link alive from Ajaxian as well as other people’s blogs. Here is the Ajaxian article. Feel free to continue giving me props in the comment thread.
-David
Post:
If you’ve been working with the Ajax framework long enough, I’m sure you’ve run into at least a few speed bumps thanks to Internet Explorer. Not a day goes by that i don’t have to rewrite a line of code, or tweak my css in order for IE to render what i think it should. But alas, this is the nature of software that comes from a company that views Standard Compliances as recommendations.
So my latest headache arose while working a project at work. To avoid mudding up this article with frivolous details, i’ll just say that I was requesting a new image via xmlhttprequest given some user defined parameters. My problem was that if the url for the java servlet (e.g. ’servlet/imagemaker.jsp?foo=bar&goo=car’) had been requested recently, IE presumed that it didn’t need to ask the server for that url again.
I tried setting the Last-Modified, Date, Cache-Control headers so that it shouldn’t cache anything. As expected, that didn’t fix it. I tried setting the If-Modified-Since header so it would think that the cache it had was outdated - no good. Finally, in an act of desperation, i disabled asynchronity in my xmlhttprequest, and to my dismay - it worked. I say that because i dont want to disable the most attractive part of the Ajax request - now none of my nice “loading…” animations would happen, as a matter of fact, anything i had put into the onReadyStateChange listener was merely executed after the transfer was complete. Ouch.
So i lived with it for a day. This morning i seeing if there was another way to initialize some funtions at the beginning of my transfer so i could re-enable my loading screen (and other background things). In doing so, i came across the Wikipedia article on Ajax (which i’d never read). So i scan through it, click a few links deep, and end up at the XMLHTTP Wiki. While scanning this particular entry, i saw something that stopped my in my tracks - like an ADD kid seeing something shiny - the first thing in the “Known Issues” section:
Microsoft Internet Explorer Cache issues
Oh hotness. Within seconds i learn that IE thinks that GET requests are supposed to all be cached (for whatever asinine reason), and a simple fix is to change your request to the POST method. Giddy as a school girl, i rush into my code and update literally 2 lines, and viola! All better.
Moral of the story: Use the POST method in your Ajax transfer unless you need to use GET for some particular reason. Oh, and always read the Wiki first.
Comment Thread:
61 People had this to say…
- Marc Said…
-
Just put and additional variable at the end of the querystring in the GET
For example:
servlet/imagemaker.jsp?foo=bar&goo=car
Change to:
’servlet/imagemaker.jsp?foo=bar&goo=car&time=111111111
Here is function to uncache the url:
function uncache(url){
var d = new Date();
var time = d.getTime();
return url + ‘&time=’+time;
}
- Rob Cluett Said…
-
You saved me 4 hours of banging my head against a wall and trashing prototype.js. Thanks for posting this. It was VERY helpful to me.
- YodaYid Said…
-
You saved my butt as well! I was pretty much going to do exactly what you did - Cache-Control headers, etc. And I doubt I would have ever thought of POST on my own.
Thanks!
–YY
- Gailo Said…
-
Thannks a lot that saved me a lot of pain in the ass too !
Gailo
- tricklin » Blog Archive » My First AJAX Experience Said…
-
[…] What To Watch Out For Internet Explorer loves to cache everything. This is particularly a problem when you are using AJAX. What works well in Firefox, may not seem like it’s working in IE. I learned this the hard way. The application I implemented AJAX on is my personal online checkbook register. So the idea was to allow a user to stay on one page, add a new transaction, submit it, and have the list show the latest transaction while also changing the account balance all without refreshing the window. This worked great in Firefox, yet nothing seemed to be happening in IE. When in actuality, the database inserts were definitely happening, yet the list refresh was not happening. It took me a while to figure out what and why this was happening, but finally figured it out when I came across this article “Ajax IE caching issue“. It seems as though IE believes that GET requests (method=”get”) need to be cached, while POST requests are not. This meant changing all my requests from GETs to POSTs. Finding out how to do this took a bit of research as well, so I’m going to just give this to you here (if you already know how to do this, then feel free to ignore the following). The solution, as you’ll see is extremely simple (changes are marked in bold & italic): Example GET request: […]
- Allan Said…
-
Oh my Word! This was such a headache for me. This should be enblazend everywhere and pretyy much upfront at the prototype site.
geezus, what an incredible impact on time this issue must have in total for all those this impacts.
- Mark M Said…
-
Thanks - this just bit me and it’s 11:42pm so I’m totally not in the mood for IE’s cr*p.
- gLes Said…
-
To my greatest dismay, even POST didn’t help me
I’m using POST mixed with GET variables, so like I send a POST request with one POST variable and a couple of others in the URL…
I tried the response headers - no use…
I tried random POST variables - nothing
I tried random variables in the URL - like it wasn’t there
I tried setting If-Modified-Since request header - didn’t help
I’ve seemed to run out of ideas
(I always cleared cache before trying)
Anyone?
- Matthew Said…
-
Thank you! Exacly what my headache was about.
- Fozzy Said…
-
I tried this… as it turns out, you need to include a variable with the POST method for IE to actually not used a cached version.
http.open(’post’, ‘myfile.php’);
http.setRequestHeader(’Content-Type’, ‘application/x-www-form-urlencoded’);
http.onreadystatechange = handleResponse;
http.send(’var=1′); // a NULL or empty string value (’’) will cause IE to use a cache
- david » Blog Archive » Ajax IE caching issue - recap Said…
-
[…] In light of the comments on the original post, i thought it would be nice to reiterate some other people’s workarounds. […]
- gLes Said…
-
No, this doesn’t work either, now mine looks something like this:
xmlhttp.open(”POST”, url + “&random=” + Math.random(), true);
xmlhttp.onreadystatechange = trigger;
xmlhttp.setRequestHeader(”Content-Type”, “application/x-www-form-urlencoded;charset=iso-8859-2″);
xmlhttp.send(”ajax=1″);
But still no use in IE
- Administrator Said…
-
gLes: try not setting the request header, also your problem could be on the server side. what are the specifics of your issue?
- gLes Said…
-
The request header has to be set, otherwise the POST variable is lost.
Meanwhile it began working, though I don’t remember doing anything quite different.
On the serverside I send these headers:
header(’Content-Type: text/html; charset=iso-8859-2′);
header(’Last-Modified: ‘.gmdate(’D, d M Y H:i:s’).’ GMT’);
header(’Expires: Thu, 19 Nov 1981 08:52:00 GMT’);
header(’Cache-Control: no-store, no-cache, must-revalidate’);
header(’Cache-Control: post-check=0, pre-check=0′, false);
header(’Pragma: no-cache’);
(I wanted to make sure it goes well)
And as I wrote before I put a random variable in the URL.
Now I don’t know which one of these worked, but I don’t want to mess around with it anymore, as long as it works 
- Dan Said…
-
Holy crap… thanks you! I just spent two hours questioning my sanity as packet captures showed no request data at all, yet the status on every call was 200. Who knows much more time I wouldn’t spent had I not come across this post.
F’n IE…
- franc Said…
-
but:
http://www.cs.tut.fi/~jkorpela/forms/methods.html
isnt it right though to cash the GETs?
with GET you get things which never change?
hm.
- Administrator Said…
-
Franc: yes, traditionally browsers would be inclined to cache GET requests and not POSTS (http://www.cs.tut.fi/~jkorpela/forms/methods.html#why) But it is not inherit in the nature of a GET request to be cached.
- EricLaw [MSFT] Said…
-
Anyone got a repro page handy? We’d like to fix this if it still repros in IE7.
- Santhosh Said…
-
Thank you David & Mark . I spend a couple of hours to reproduce this issue and finally figured out IE was caching my get request. You made my day with the workaround
- Candi González Said…
-
Thanks very much for the solution to that problem! Last week I had to suffer this problem and could not solve it until this morning, when I entered this blog! What a great week starting!!
- Dave Said…
-
I tried changing to “POST” from “GET” and it fixed my IE problem and at the same time broke it for FF. I’m trying to get some XML via JavaScript. Any ideas anyone?
- steve Said…
-
thanks mate for that… saved us loads of time!!!
- yulinxp Said…
-
Here is the solution for GET method.
http://weblogs.asp.net/pleloup/archive/2006/06/08/451583.aspx?CommentPosted=true#commentmessage
- Administrator Said…
-
yulinxp-
dually noted, however that solution has been covered.
see Mark’s comment above, which is also highlighted in the recap of this post: http://www.enja.org/david/?p=44
I should say that this is the workaround i use. I construct a timestamp string with the seconds and milliseconds.
- Anonymous Said…
-
I used this and it works
function zlapSend(req) {
//IE Cache work around
var d = new Date();
var time = d.getTime();
if(req.indexOf(’?’)>=0) {
ser.open(’get’, req+’&’+time+’=’+time);
} else {
ser.open(’get’, req+’?’+time+’=’+time);
}
ser.onreadystatechange = zlapResponse;
ser.send(null);
}
- Josh Said…
-
I’ve been struggling with this all morning, this post was a God send. Thanks!
- Jay Said…
-
Nice one - I’ve be banging my head on the desk over that one for some time!! Cheers for the heads-up…
- PWilly Said…
-
Oh god, you’ve satisfied my curiosity. I found ways around with the currTime thing, but always NEEDED to know why. Now I’m always using POST for the requests.
ThankYouThankYouThankYouThankYou
- divi Said…
-
i love you thanks :*
- I am John Said…
-
I found this article both humorous and helpful. Thanks!
- Mark Said…
-
Dude, thanks for this. was looking for this ’simple’ fix and read though so many ’so called fixes’. your solution not only fixed my issue but made me smile!!
- Warren Said…
-
thank you very much! this post was the first one I found in google after struggling with this issue for hours. a witty and effective post.
- Frank’s Blog » Blog Archive » Ajax: Internet Explorer Cache Problem Said…
-
[…] http://www.enja.org/david/?p=25 […]
- fallenrogue Said…
-
thank you. You just saved me reading the documentation. damn you IE!!!!
- Ajaxian » Ajax IE Caching Issue Said…
-
[…] David Arthur, like many, has had problems with the caching issue that Internet Explorer seems to have with Ajax connections: If you’ve been working with the Ajax framework long enough, i’m sure you’ve run into at least a few speed bumps thanks to Internet Explorer. Not a day goes by that i don’t have to rewrite a line of code, or tweak my css in order for IE to render what i think it should. But alas, this is the nature of software that comes from a company that views Standard Compliances as recommendations. […]
- mdm-adph Said…
-
Wow — nice to know that someone else other than me was having these same problems. (Was pulling my hair out for weeks trying to figure out why IE was doing this lame-brained behavior. Luckily, it wasn’t a big bug in my program, so I was able to space out my debugging.)
Weirdly enough, I only had this bug appear with some XML strings — I’ve never figured out the difference, though I think it has something to do with the platform I’m programming on (Lotus Domino).
Oh yeah — never thought about doing a POST instead of a GET — what worked for me was attaching a random variable to the end of the calling URL.
- Mark Kahn Said…
-
Just add a random querystring:
…(’somefile.php?a=5&b=10&r=’+Math.random())
IE no longer sees it as the same page.
- Marko Said…
-
The asinine reason for caching is HTTP RFC, which clearly states that GET requests can be cached.
They don’t have to be, but browser is performing per spec if it does the caching.
- Markus Said…
-
Funny how I saved myself from the problem. From the first day I never ever considered using GET. Why? Simply, as we all know, GET requests are limited to, whatever I don’t know it exactly, amounts of characters. So since for Ajax I didn’t wanted to care about this I’ve always used post. And when I sent GET requests, which I almost only did for updating img src attributes (ok, this has nothing to do with ajax) I’m always using the “random file name”-principle: I request the file as http://server/controller/action/parameter/.png. Always works.
- Mario Said…
-
This problem has nothing to do with Prototype.
- Nadav Said…
-
I prefer to set the headers right. It works nice both with GET and POST request and it is tested with IE and Firefox.
I explained once
in my blog how to do set the headers correctly using CherryPy/TurboGears.
The basic thing is to set the headers right:
Expires: Sun, 19 Nov 1978 05:00:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
- NitinPai Said…
-
Wow! That was an amazing experience David and its even more pleasure that your have shared it with all the developers.
It never crossed my mind about that GET or POST could cook up such an issue. But its very nice to known that complex problems can have the simplest of solutions
- Daniel Chacón Sánchez Said…
-
In my case the solution was include this on my jsp:
Hope it helps, java programmers. Regards
- Zeev Halevi Said…
-
Thanks, I almost gave up using prototype because of different behavior with FF and IE.
Added to Ajax.Updater :
var d = new Date();
var time = d.getTime();
if (url.indexOf(’?’) > 0)
url = url+’&prevent_cache=’+time;
else
url = url+’?prevent_cache=’+time;
just before: this.request(url);
And now I am happy…
- Raman Said…
-
thanks Zeev Halevi. Its all nice that you have been able to do it. But can you explain how to use prevent_cache and what to do with that
url = url+’&prevent_cache=’+time;
Any idea?
- linhph Said…
-
oops, thanks so much, I met that goddamned problem for the whole morning
, thankss
- fortran rules Said…
-
The single most useful tip I have encountered … ever.
- joren Said…
-
yes i am as most of you, having the problem that IE caching the data, now using the POST solves my problem, and headache of couple of weeks
gracias
- mike whn Said…
-
I am an ajax beginner,
do you guys ever had problem like me?
I changed from POST to GET, but the Request still consider as POST.
I already refreshed the browser and restart the server, still give me the same problem.
This is what I changed:
xmlHttpReq.open(’GET’, strURL, true);
This is the HTTP header:
POST /springapp/AjaxService HTTP/1.1
Accept: */*
Accept-Language: en-us
Referer: http://localhost:9080/springapp/ajax1.html
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)
Host: localhost:9080
Content-Length: 45419
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: CP=null*
a=1112&w=hello
- Ian Said…
-
Marko said:
The asinine reason for caching is HTTP RFC, which clearly states that GET requests can be cached.
Hmmm, here is what HTTP/1.1 RFC2616 says:
Unless the origin server explicitly prohibits the caching of their responses, the application of GET and HEAD methods to any resources SHOULD NOT have side effects that would lead to erroneous behavior if these responses are taken from a cache. They MAY still have side effects, but a cache is not required to consider such side effects in its caching decisions. Caches are always expected to observe an origin server’s explicit restrictions on caching.
We note one exception to this rule: since some applications have traditionally used GETs and HEADs with query URLs (those containing a “?” in the rel_path part) to perform operations with significant side effects, caches MUST NOT treat responses to such URIs as fresh unless the server provides an explicit expiration time. This specifically means that responses from HTTP/1.0 servers for such URIs SHOULD NOT be taken from a cache. See section 9.1.1 for related information.”
As I understand that, GETs with QUERY URLs, unless exlicity cacheable, must not be cached…
RFC 2616 Sec 13.9
- Fábio Vedovelli Said…
-
PORTUGUESE
Encontrei uma solução inserindo o código
req.setRequestHeader(’Content-Type’, ‘application/x-www-form-urlencoded’);
inclusive quando usando o método GET. Funcionou para me livrar do cache do Internet Explorer. O método descrito, usando getTime() não funcionou para mim.
ENGLISH
Found a solution inserting
req.setRequestHeader(’Content-Type’, ‘application/x-www-form-urlencoded’);
even when using GET method. Worked fine to workaround with the IR cache problem. The method described in this post did not work for me.
Thanks!
- Westy Said…
-
Thank you for saving me so much pain! I ran into the issues, suspected a caching issue and found this article straight away! Entire process took 10 minutes thanks to you… otherwise it would have been hell.
Thanks!
- Sanjay Said…
-
Awesome find dude, have saved me a whole bunch of time, nice one!!!
- benimaur Said…
-
Much thanks! I was almost going to give up AJAX in my application…
- hebiryu Said…
-
thank you sooooo much david.
you saved my life.
may I use your tips in my blog. i will translate it into indonesian.
thanx again.
- Anonymous Said…
-
thank you!
it works nicely now!!!!!!!!
really thanks a lot!!!
- Kartik Said…
-
THX THX THX…. lots of thx man…. !!! 
- Alexandre Lemieux Said…
-
You saved my life! Thanks!
- Huw Said…
-
*punches the air with joy*
- Mike Said…
-
Thank you!!
- Graham Said…
-
You are da man. Massive props for this.
Tags: ajax, archive, ie, internet, javascript, xmlhttp
Posted in archives | 1 Comment »
June 27th, 2008
In lieu of my typical witty banter I’m just going to post some code. Way too tired to put any effort forth.
Tried for days to get Access to export my ADO Recordset as something, anything. I tired:
- Loading it into a table - nope
- Making a temporary table on the database server and linking to it - nope
- Tried using getRows and manually creating a CSV - nope
- Conjured up the ancient spirits of BASIC - nope
I mean really. And the internet was of course no help. Turns out there’s a few built-ins that do the trick - go figure.
Problem: Need to export the data… why oh, why can’t I export the data
XML Solution:
Dim ADOrs As ADODB.Recordset
Set ADOrs = Me.RecordsetClone
ADOrs.Save "export.xml", adPersistXML
ADOrs.Close
Shoot me in the face that was easy.
CSV Solution:
Dim ADOrs As ADODB.Recordset
Set ADOrs = Me.RecordsetClone
Dim csv As String
csv = ADOrs.GetString(, , """,""", """" _
& vbCrLf & """", "")
csv = Left$(csv , Len(csv) - 1)
Dim h As String ' Header row
For X = 1 To ADOrs.fields.Count - 1
h = h & """" & ADOrs.fields(X).Name & """"
If X < ADOrs.fields.Count - 1 Then
h = h & ","
End If
Next X
Open "export.csv" For Output As #1
Print #1, h
Print #1, """", csv
Close 1
Edit: An interesting note about the ADO Recordset XML export. It uses a special namespace (actually a few). It’s readable enough, and just as easily parsible as any other XML document. A nice feature about this XML spec is that you can load it back into Access as an ADO recordset - so in theory this could be used for long-term caching of large chunks of data.
Tags: Access Nightmares, data, shootmeintheface, vb, xml
Posted in Access Nightmares | No Comments »
June 23rd, 2008
Just a quick blurb. I had a problem with CodeIgniter regenerating the session id all willy-nilly.
Here’s a snip from the config.
$config['sess_cookie_name'] = ‘ci_session’;
$config['sess_expiration'] = 54000;
$config['sess_encrypt_cookie'] = TRUE;
$config['sess_use_database'] = TRUE;
$config['sess_table_name'] = ’sessions’;
$config['sess_match_ip'] = TRUE;
$config['sess_match_useragent'] = TRUE;
$config['sess_time_to_update'] = 300;
Turns out, CodeIgniter will regenerate the session id every time it updates the session table in the database. So, by default the session id gets regenerated every 5 mins (300 seconds). Instead of changing the sess_time_to_update value, I dug around in the code for a bit.
Here’s the culprit. (In basedir/system/libraries/Session.php)
$old_sessid = $this->userdata['session_id'];
$new_sessid = “”;
while (strlen($new_sessid) < 32)
$new_sessid .= mt_rand(0,mt_getrandmax());
$new_sessid = md5(uniqid($new_sessid,True));
Talk about entropy…
Quick hack: comment out these lines and set $new_sessid = $this->userdata['session_id'];
Bang. Zoom. Straight to the Moon.
Tags: ci, codeigniter, hacks, php
Posted in Code Igniter | 2 Comments »
June 23rd, 2008
The title is rather representative of the conceit of this post. Suppose you have a form with several subforms that you arrange in a tabular manner (I think Access calls them pages). Now you probably don’t want to show every tab unless there is some content within that tab worth seeing, so we write a routine which (upon loading the parent form) will quickly check the subforms’ recordsets and see if they have any data in them.
Problem: Automatically check for content within subforms arranged in a tabular manner, and do something as a result of content/no content.
Solution: Well, keep reading.
Basically, what we’ll do is create a collection for the subforms and a collection for the pages. It is necessary to make sure these collections “line up” - meaning item 1 in the form collection corresponds with item 1 in the pages collection. VB doesn’t really have a good data structure for this sort of thing - well, I suppose you could make a 2d collection. You implement it how you see fit.
Code:
Dim mySubForms As New Collection
mySubForms.Add Me.sfrmCasing
mySubForms.Add Me.sfrmFormation
mySubForms.Add Me.sfrmGPLog
Dim myPages As New Collection
myPages.Add Me.pgCasing
myPages.Add Me.pgFormation
myPages.Add Me.pgGPLog
Dim rs As Recordset
Dim i As Integer
For i = 1 To mySubForms.Count
Set rs = mySubForms.Item(i).Form.RecordsetClone
If (rs.RecordCount = 0) Then
myPages.Item(i).Visible = False
Else
myPages.Item(i).Visible = True
End If
Next i
Pretty straightforward. Loop through each subform, see if there’s any data there, if so set the visibility of the corresponding page to True, otherwise set it to False. The same basic idea could be used to embolden a page title when there’s data - instead of showing/hiding, you would change the font style of the page caption.
Using all this Access jargon is making me noxious - I’m going to go write some Python.
-David
Tags: Access Nightmares, forms, vb
Posted in Access Nightmares | No Comments »
June 20th, 2008
So here’s a fun fact - when you are browsing data displayed in a Continuous Form or a Datasheet, Access takes it upon itself to requery the database a gagillion times to make sure you have the latest token of data.

After a little experimenting, I found that: clicking into a field, mouseing over a button, or scrolling through results causes Access to query the database. I confirmed this using Windows’ network manager, as well as monitoring the database itself. Since I am going to be utilizing continuous forms quite often, I needed to find a fix for this.
For you impatient types, the short answer is ADODB. Read on for explaination.
Problem: Need to cache recordsets so Access won’t kill the server when using a continuous form or datasheet.
Solution: Manually set the recordset for my sub-form using an ADODB connection and recordset.
My first attempt at this led me to the fillCache method for a recordset. Microsoft’s documentation is less than inspiring (http://msdn.microsoft.com/en-us/library/bb221030.aspx), but the basic idea is you set the cursor location (bookmark) and the number of records you want to cache, and the Jet engine will handle the rest. Well, this is not really all that true. I was suprised to see very little documentation, or discussion about the fillCache method on the interwebs, but I can only assume that’s because it doesn’t really work.
I’ll spare you the 2 hour journey through google search results and books off my shelf.
Code:
Open the Connection
Dim con AS ADODB.Connection
Dim rs AS ADODB.Recordset
Set con = New ADODB.Connection
con.open "Data Source=MyDataSource;" _
& "Initial Catalog=MyDB;" _
& "User ID=joepublic;" _
& "Password=foobar"
Create the load the recordset
Set rs = New ADODB.Recordset
rs.CursorLocation = dbUseClient
rs.Open "SELECT fields FROM table WHERE id = " _
& Me.id_from_parent_form, con
Clean up and update the recordset of the form
Set rs.ActiveConnection = Nothing
con.Close
Set Me.sfrmSomeSubForm.Form.Recordset = rs
rs.Close
Set rs = Nothing
Now, the ADODB connection and recordsets are closed and gone, but the data remains in memory. Huzzah! N.B., there are several options for the Open method of the ADODB Recordset which should not be overlooked. You can find more info on that in the VB help files if you search for “ado recordset open”.
Cheers
Tags: Access Nightmares, ado, vb
Posted in Access Nightmares | No Comments »
June 20th, 2008
VBA, Visual Basic for Applications, is quite possibly the worst “programming language” I’ve ever had the horrific indignity of working with. The documentation is non-existent. The developer community is a stew of miscreant “Access developers” who don’t know anything about databases or “Database developers” who have no inclination for user interface.
Somehow, This is my job now. Building an Access interface for an extremely complex and robust database I created in PostgreSQL. In nearly daily battles, I encounter (or at least foresee) implementation problems which I inevitably must face. I figure I’ll share my findings here to spare someone the trouble.
Disclaimer: I am not an Access developer, or VB programmer, or database guru. I’m a grad student in Computational Science who some how ended up in this job.
Posted in Access Nightmares | No Comments »