You know how you can put a spreadsheet on a shared drive, and then anyone can use it, but only one person can use it at a time?
Well, I just got around that limitation.
I work for a huge law firm. We send our closed case files to offsite storage, but we frequently have to bring some of those files back because the attorney needs something from the file, or the case went to a higher court, or something. Among other things, I order and deliver these cases. People send me emails requesting the case they want, and I place the order, and email them back to tell them I've ordered them. When the files arrive, I have to email people again to tell them that their files have arrived. It's a lot of email back and forth for basically nothing, and I got sick and tired of it.
I envisioned a system where users would launch an application and enter their offsite file requests. On the other side, I would launch the application, see those offsite file requests, order them, and then set statuses so that users could check and see if their file had been ordered, received, delivered, or what. We have a network, of course, but we don't have any server database, and we don't even have Access. All we have is Excel, so here's what I did to allow everyone to access the same spreadsheet without error messages or having to open the spreadsheet read-only. Here's how I did it.
First, I put a spreadsheet called server.xlsx on the server. This spreadsheet has no macros. It just contains the data.
Separately, on everyone's workstation, I put a spreadsheet called client.xlsx. This spreadsheet has all the VBA code. When a user needs to request an offsite file, he or she launches the application, which presents the user with a form. When the user fills out the form and submits it, the code opens the server spreadsheet, enters the row of data, closes the server spreadsheet, and shows the user a "done" message. Bam, bam, milliseconds.
On my side, I launch the application, get my little dashboard, and click the button for new requests. The code behind the button opens the server spreadsheet, grabs the new requests, copies them to my local client spreadsheet, and closes the server spreadsheet. Again, bam, bam, milliseconds. After I place the order for these offsite files, I again launch the application. I mark these requests as ordered, and now the users can check the status of their file requests. At all times, the client spreadsheet, under VBA control, opens the server spreadsheet only as long as it takes to get or put data.
I'm basically treating the server spreadsheet as if it were a database. For example, here are two functions to open and close the server spreadsheet.
(appData is a user defined variable I use to keep app data).
Here's how I use it. This code deletes a request record. It opens the server spreadsheet in "write" mode, arm-waving ensues, and then it closes the server spreadsheet in "save" mode (the arm-waving finds the record and deletes it).
Like I said, milliseconds.
Of course, this is not real multi-user. Collisions are still possible; it's just that they're very unlikely in an ordinary office environment, where maybe a dozen people access a resource in what seems to be "at the same time."
For our purposes, this works great! The users like it because they can check on their file requests without having to wait for me to email them back.
Truthfully, I always knew it would work in theory, but I was skeptical about it working in the practice. But it worked fine. There's a blinking of the screen as the application opens and closes the server spreadsheet, but the user experience is remarkably smooth, even on PCs of ordinary power.
Well, I just got around that limitation.
I work for a huge law firm. We send our closed case files to offsite storage, but we frequently have to bring some of those files back because the attorney needs something from the file, or the case went to a higher court, or something. Among other things, I order and deliver these cases. People send me emails requesting the case they want, and I place the order, and email them back to tell them I've ordered them. When the files arrive, I have to email people again to tell them that their files have arrived. It's a lot of email back and forth for basically nothing, and I got sick and tired of it.
I envisioned a system where users would launch an application and enter their offsite file requests. On the other side, I would launch the application, see those offsite file requests, order them, and then set statuses so that users could check and see if their file had been ordered, received, delivered, or what. We have a network, of course, but we don't have any server database, and we don't even have Access. All we have is Excel, so here's what I did to allow everyone to access the same spreadsheet without error messages or having to open the spreadsheet read-only. Here's how I did it.
First, I put a spreadsheet called server.xlsx on the server. This spreadsheet has no macros. It just contains the data.
Separately, on everyone's workstation, I put a spreadsheet called client.xlsx. This spreadsheet has all the VBA code. When a user needs to request an offsite file, he or she launches the application, which presents the user with a form. When the user fills out the form and submits it, the code opens the server spreadsheet, enters the row of data, closes the server spreadsheet, and shows the user a "done" message. Bam, bam, milliseconds.
On my side, I launch the application, get my little dashboard, and click the button for new requests. The code behind the button opens the server spreadsheet, grabs the new requests, copies them to my local client spreadsheet, and closes the server spreadsheet. Again, bam, bam, milliseconds. After I place the order for these offsite files, I again launch the application. I mark these requests as ordered, and now the users can check the status of their file requests. At all times, the client spreadsheet, under VBA control, opens the server spreadsheet only as long as it takes to get or put data.
I'm basically treating the server spreadsheet as if it were a database. For example, here are two functions to open and close the server spreadsheet.
Code:
Public Sub ServerConnect(Optional argMode As String)
If LCase(argMode) = "w" Then 'open for write
Workbooks.Open FileName:=appData.ServerFQN
Else ' open for read
Workbooks.Open FileName:=appData.ServerFQN, ReadOnly:=True
End If
End Sub
Public Sub ServerClose(Optional argMode As String)
If LCase(argMode) = "s" Then 'save and close
If Workbooks(appData.ServerFile).Sheets(1).ListObjects(1).ShowAutoFilter = True Then
Workbooks(appData.ServerFile).Sheets(1).ListObjects(1).AutoFilter.ShowAllData
End If
Workbooks(appData.ServerFile).Save
End If
Workbooks(appData.ServerFile).Close SaveChanges:=False
End Sub
(appData is a user defined variable I use to keep app data).
Here's how I use it. This code deletes a request record. It opens the server spreadsheet in "write" mode, arm-waving ensues, and then it closes the server spreadsheet in "save" mode (the arm-waving finds the record and deletes it).
Code:
Public Sub DeleteRequest()
Dim tbl As ListObject
Dim key As Range
Dim deleteRow As Range
ServerConnect "w"
Set tbl = Workbooks(appData.ServerFile).Sheets(1).ListObjects(1)
Set key = tbl.ListColumns(1).Range.Find(gRecord(1, RecFlds.RecID))
Set deleteRow = key.EntireRow.Resize(1, kFieldCount)
Application.DisplayAlerts = False
deleteRow.Delete
Application.DisplayAlerts = True
ServerClose "s"
End Sub
Like I said, milliseconds.
Of course, this is not real multi-user. Collisions are still possible; it's just that they're very unlikely in an ordinary office environment, where maybe a dozen people access a resource in what seems to be "at the same time."
For our purposes, this works great! The users like it because they can check on their file requests without having to wait for me to email them back.
Truthfully, I always knew it would work in theory, but I was skeptical about it working in the practice. But it worked fine. There's a blinking of the screen as the application opens and closes the server spreadsheet, but the user experience is remarkably smooth, even on PCs of ordinary power.