Date reflects incorrectly due to Time Zone setting on Sharepoint - vba

We're using an Access application that stores and retrieves information from SharePoint, and the times and dates get viewed through the 'filter' of the Time Zone settings on SharePoint.
This has started to cause a problem when just trying to enter a date with no time. People marked as CST will see 7/1/2014 0:00, but those in PST will see 6/30/2014 22:00. Calculations that organise metrics by date would then show the same entry in June for PST users and July for CST.
Is there a way to adjust for this? I don't WANT to be capturing a time in this field, but since it's a Date/Time field on SharePoint, it's attaching a time anyway. Would changing the field in question to 'String' work or would that cause more problems than a more adaptive solution?
(I've read links that popped up in 'Questions that may already have your answer', conducted other searches on and off Stack.)

After a bit of testing after all my Users went home except for one, I found that just changing the type on SharePoint for the fields in question from 'Date/Time' to 'Text (Single Line)' worked perfectly. My Tester had no issues with the VB used to store information and bringing up the raw tables showed the 'proper' date stamps after a restart of the client database.
It seems a little too good to be true, but it appears to be a victory! I'll definitely come back here with an update if anything blows up.

Related

How to force a cache refresh in MS Access

I am working on migrating a MS Access Database over to a newer SQL platform.
But, with all of the users who are currently using it, we're migrating slowly/carefully.
The first step is that we are re-writing the VBA code into C#, which is then deployed in a .dll along with the database.
Now, the VBA code calls into the C# to do the business logic, then the VBA continues to do the displays/UI, while Access still hosts the database.
The problem comes in that I have a report that is being run after the business logic from the C# in one place, and apparently MS Access has a cache, which clears every 5 seconds. So, the transaction that occurs in the C# code writes to the database, but the VBA code is still using the cache. This is causing errors, as the records added to the database (which the VBA report is trying to report on) don't exist in the cache yet...
I'm guessing that the C# .dll must be getting treated as a "second connection" to the MS Access database, which is what seems to typically cause this error in my searches (thinks that one process is writing, and the other is reading).
Since the cache is cleared out every 5 seconds, we can just put the process to sleep, and wake it up after 5 seconds, and then run the report, but that's pretty terrible for an end user.
And, making things difficult, the cache seems like it only gets used in the deployed version (so, when running from source / in debug mode, the error never happens).
Doing some searches, there seems to be plenty of people who have said "just refresh the cache." But, the question is: within VBA, how do you refresh the cache?
Any advice would be welcome.
Thanks
I've been fighting the same issue for years as I write a lot of tools around an old Powerbuilder application that has an Access MDB back end.
The cache does exist and it is VERY real. When data is inserted on a different connection than it is queried on, the cache can be directly observed and measured. It was also documented by Microsoft before they blackholed a bunch of their old articles...
Microsoft Jet has a read-cache that is updated every PageTimeout milliseconds (default is 5000ms = 5 seconds). It also has a lazy-write mechanism that operates on a separate thread to main processing and thus writes changes to disk asynchronously. These two mechanisms help boost performance, but in certain situations that require high concurrency, they may create problems.
I've found a couple workarounds that are not the best, but somewhat make due until I find something better or can re-write the app with a better back end database.
The seemingly best answer I've found (that may actually work for you since you say you need VBA) is to use JRO.RefreshCache. I've been trying to figure out how to implement this using C# or VB.net without any luck. Below is a link to a code example where you execute the RefreshCache method on your 2nd connection that needs to pull the data. I have not tested this myself.
https://documentation.help/MSJRO/jrmthrefreshcachex.htm
A workaround I've found that will deliver the query results within 500ms to 1000ms of insert time (instead of anywhere between 500 and 5000 ms - or more):
Use System.Data.ODBC instead of OleDB, with connection string: Driver={Microsoft Access Driver (*.mdb, *.accdb)};Dbq=;
If someone knows how to use the JRO.RefreshCache method with OLEDB and C# or VB.net, I'd be forever grateful. I believe the issue is it's looking for an ADO connection to be passed in, not an OLEDB connection.
I not aware of ANY suggesting that some 5 second cache exits? Where did this idea come from????
Furthermore, if you have 5 users, then you not going to be able to update their cache, are you?
In other words, the issue of some cache for one user still not going to solve or work with mutli-users anyway, is it?
The simple matter is if you load up a form with 100 reocrds, and then other users are ALSO working on that 100 rows, then all users will not see other changes until such time you tell access to re-load the form.
You can do this with a me.Refresh in the form, and then it will show changes made by other users (or even your c# code!!!).
However, that not really the soluion here.
How does near EVERY system deal with this issue?
Answer:
You don't, you "design" the software to take the user work flow into account.
So, in place of loading up a form with 100 rows of data? (which you should not, unless SUPER DUPER reason exists for doing that).
The you provide a UI in which the user FIRST searches for whatever it is they want to work on.
In other words, say you just booked a user on a tour. Now, they call the office back, and want to change some details of that tour. But, a different tour staff might pick up the phone. So, now a 2nd user opens the tour?
So, you solve that issue by NOT loading all the tours into that form in the first place.
you provide a search screen, so they can search for the user, find the user, maybe type in a invoice number or whatever.
You display the results in a pick list, and then launch the form to the ONE record (and perhaps detail records from child tables).
So there no concpet of a cache in Access anymore then there is in c#.
However, if you load up a datatable in c#, and then display that data?
Well, what about the other users on that system. They will not see changes to that data ANY MORE then the current access form.
So, if you want to update some data in c#? Then fine, but you need/want to do two things:
First, before you call any c# code that may update the current form reocrd? You need to FORCE a data save of that current record BEFORE you call any code, be it VBA code, or c# code that going to update that current reocrd the user is working on.
You can in Access save the current reocrd in MANY different ways, but the typical approach is:
' single record save - current record
if me.dirty then me.dirty = false
' VBA or c# code goes here.
' optional refresh the current form to reflect changes
me.Refresh
So, in most cases, it is the "design" of your software that will solve this issue.
For example, in the tour example, or in fact ANY system, the user can't work, can't update, and can't do their job UNLESS they first find/search and have a means to bring up that form + record data in the first place.
So, ANY typical good design will:
Ask the user for that name, invoce number or whatever.
Display the results of the search, and THEN allow the user to pick the record/data to work on. When they are done, they close that form and are RIGHT BACK to the search form to do battle with the next customer or task or phone call or whatever.
So, a search form might look like this:
In above, I typed in smi, and then displayed a pick list.
The user can further type in say part of the first name, and thus now get this:
So, maybe they type in a invoice number, customer number, booking number or whatever.
So, you display the results, and then they can select the row or "thing" to work on.
thus, we click on the row (or above glasses button), and then jump to the ONE record.
so, the user does whatever they have to do with the customer. Now, when done, they close the ONE thing, the ONE main reocrd.
This not only saves the data (so others in the office can now use that booking data), but it also means the data is saved. and they are NOW right back at the search screen, ready to do battle with the next customer.
So, not only does this mean we have a VERY bandwith friednly design (we only pull the one main reocrd into that form), but it also is better for work flow.
The Access form's cache thus becomes a non issue, since we only dealing with the one record.
And as I pointed out, if the system is multi-user, then you NOT going to be able to udpate and deal with multiple users cached data anyway, are you?
Think of ANY system you EVER used from a software point of view.
When you use google, does it download the WHOLE internet, and then you use ctrl-f to search megs and megs of data in the browser?
Nope!
you search first, get a list of that search, and THEN pick one!!
And when that list is display, maybe others on the internet are udpateing, and add new data - but if that was cached in your browser, then it would not work!!!
And same goes for a desktop accounting system. You don't load up all accounts, and THEN have the user go ctrl-f to search all the data. You search for the customer, invoice number and PICK ONE to work on.
And it does not make sense to load up a form with 1000 customers, and then go ctrl-f to find that customer. Same goes for a instant banking machine. It does not download ALL customers and THEN let you search. It asks you FIRST to get what you need. So, be it browser based, desktop based, or JUST ABOUT ANY software you use?
You quite much elminate the cache issue, since not pre-loading boatloads of data, but asking and letting the user search for the data they need.
So, in regards to the Access form data and cache?
If you are on a form, and call VBA code, or c# code or whatever?
If that code update the current form, you have NO MORE OR LESS of a issue when calling VBA code, or c# code!!!! If that code updates the current form, and the reocrd is dirty (has pending edits), then you get that message about the current form's reocrd having been udpated by another user!!!
So, your cache issue does NOT IN ANY WAY exist MORE or LESS as a issue in typical Access software.
As a genreal rule, if you are on a form with pending edits, and say want to pop up some form to edit releated data?
You have to ensure that pending edits are SAVED before you launch an form that can edit the same data, or run code that can/may edit that data.
As a result, ZERO cache issues should exist, and they no more or no less exist when calling sql or VBA update code in a form then calling some c# code from that form.
So, write the pending update for that form.
Then run your VBA, SQL, or c# code.
And then do a me.Refresh to display any changes made by those external routines.
there is no documetjion, or ANY article I can find that suggests some kind of 5 seocnd cache or update - it is a urban myth, and your software challenge here in regards to use c# or VBA, or even SQL server stored procedures?
They are all the same issue, and I dare say that often access is used as a front end to SQL server, and ALL OF the SAME issues exist when using SQL server with ms-access.

<DateTimeInput> converts time to UTC when saving

Thanks for adding DateTimeInput! I have a bit of a problem with it, though. It converts the entered time into UTC using my local timezone (decreases 2 hours from the entered time). Is there a way to make it simply save the time that's entered?
I didn't find any info about any options this component accepts.
EDIT:
Nobody has any answer to this problem? I'm sure I'm not the only one who wants to be able to store date/time values from the UI "as-is", instead of some automatic conversions.
In our case we enter certain measurement data from different locations. The location of the UI user here is irrelevant and the automatic conversion simply messes things up.

expire application after 1 year span from client PC, No internet is available on client PC

I have one vb.net windows application and I want to deliver it to my client with 1 year validity.
After one year this software will automatically stop working or ask for renewal.
The client PC doesn't have internet access.
Please tell me the secure way for this.
When the program is installed, have it set a registry value with the current date. Then, on every subsequent program start, have it check that registry value against the current time. If more than a year has passed, do whatever you plan on doing to lock up your application.
This post has some excellent info on the specifics of adding, modifying, and accessing registry values in vb.net.
Check the date.
If dateToday > dateProgramSold.AddYears(1) Then
'open form that cant be close saying program is expired
End If
When the program is installed, it should ask for an registration key (they could get it by email, print it off and type it). The key should contain the last day of validity (encrypted). Store the key in the registry (or somewhere else). When the program starts, you check the date inside the key.
If they re-install the end date will stay the same.
When they want to update, just send a new key by email or mail.
The amount of security you put into just could depend on how much you trust the company. Because they could always decompile and crack your software.
I needed to do this for a program I wrote. My final solution included the resolution that you can't be 100% foolproof, so I considered my users and did the best I could with what I had.
Without access to the internet, how does the computer know what date it is? It has to rely on user input for it. So if a user can input it, then a user can change it. There is no foolproof way to get an accurate date from the PC without the the user having access to it. Whether from the OS, the BIOS, etc.
So what I ended up doing was putting an obfuscated key into the registry in an obscure place. HKCU >> Software. I made the key just some letters and numbers {L12A3C0DFF} then I named the key Z0B0 and made the value the obfuscated date. I took the year month and day and ran each one through a different calculation. I ended up with something that looked like DDE011468932.
Each time the program ran it decoded this registry setting to see if a year had passed based on the time in the BIOS. If the date in the BIOS was earlier then this date then they changed it and I would not not allow my program to run.
Also each time the program ran, I checked the date in the BIOS and stored this in the registry in the same way. So I would check to see if they changed the date in the BIOS to an earlier date.
So in order for them to abuse the date restriction of one year, they literally had to change the date in the BIOS every day which I figured was not worth it to them to do, besides, they would have had to figure out where I was getting the date from to begin with, which would take decompiling (and I wasn't selling it to a bunch of programmers). Simply changing the date in the OS wouldn't fool it.

MS-Access VBA Date() works on one PC but not others

I am designing my first database from the ground up and I have learned a lot in the last few weeks. One thing that has been eating at me though is that on my login page I have a simple unbound text box with its control source as =Date().
This works perfectly well on the computer I use most days, but any other computer in the facility I am working out of displays #NAME? instead of the date.
I have tried changing to =Now() and it works fine on all computers. Apparently only =Date() has issues. If the fields control source is changed back to =Date() I am informed that The function you entered can't be used in this expression.
I have checked the MS-Access versions and tried on a machines with and without access.
I really need Date() to work because it is used elsewhere in more vital areas of my code and I may not be able to use Now() in its place. Any ideas as to why this may not work on any PC besides my own?
Date() is controlled by the Visual Basic For Applications X.XX reference. Make sure the reference is installed and any competing references are removed.
To do this, open the VBA window and go to Tools --> References and ensure the proper one is checked.
I suspect the issue is user's region and language settings for the date. I noticed this when I changed computers and my files wouldn't save anymore due to the slashes in the date. You should try the format() function so that your dates always have the same format and can be used across machines independent of the user's settings.
Sub Foo()
Debug.Print Date
Debug.Print format(Date, "yyyy-mm-dd")
End Sub
Output
7/23/2015
2015-07-23

.docx problems with SharePoint Designer workflow

So I have a document library with date, alert and alert-date fields.
The date and alert fields are completed when a doc is uploaded, and there is a workflow which takes the alert away from the date (and also takes an extra day off) and sets it as the alert-date. E.g. If the date is 15/07/2013, and the alert is 1 month, the workflow sets the alert-date to 14/06/013 (15/07/2013 - 1 month and a day). The alerts have options of 1 month, 3 months, 6 months or 1 year. A extra day is always taken off as these workflows are triggered by information management policy which only allows conditions of +1 day (the day is taken away via the workflow and then added via information management policy).
The problem comes when a .docx file is uploaded, as all the alert-dates (even if they relating date and alert aren't populated) are set to 01/01/1900.
I know SharePoint workflows pretty well and have never come across this problem before, so was just wandering if anyone else has and knows a solutions?
Thanks,
Josh.
Found a solution:
The alert-date fields didn't seem to be set at the same time that the workflow was looking them up (for docx files). So I added a minute pause at the beginning of the workflow which gave enough time for all the dates to be set and then for the workflow to look them up, and there are now no issues.
Thanks,
Josh.