0

Some background: I built a shared workbook which suffered a lot of save conflicts from people adding items in new rows at the same time.

The process of adding a new row of information is done via a macro, so I've created a new version where the macro saves the workbook before adding the information, therefore stopping two sets of data being put into the same row.

My issue: Saving the file is really slowing down the macro because the file is about 2 MB.

My question: Is there a way of speeding up the save process, or maybe only updating the workbook with other people's changes to save time?

Edit #1

The macro file which update the shared sheet has another primary objective. Based on the data of an local excel file, we used the macro to generate a standard text for reporting.

Based on a flag in the shared workbook user check is the issue is already reported or not.

Also this macro is used by 4 or more people at the same time which results in the conflict.

Community
  • 1
  • 1
Santhosh Rao
  • 7
  • 1
  • 9
  • 1
    This sounds like it is begging to have a database back-end. Excel simply isn't designed with concurrency controls in mind. – Comintern Mar 19 '16 at 16:01
  • Since this sheet is being update automatically by a macro. I am not clear how this can be linked to a database. I have also update the question, Please help.. – Santhosh Rao Mar 19 '16 at 16:53
  • Updating a database with the macro and linking the spreadsheet to the database is one solution. Again, you're attempting to ensure multi-user concurrency in an environment that isn't designed for it. – Comintern Mar 19 '16 at 17:10
  • If i have to choose a database can it be a access database or sql db database? – Santhosh Rao Mar 19 '16 at 17:14
  • Doesn't really matter that much - would depend on your other requirements. That said, Access via ADO is perfectly capable of handling 4 users. – Comintern Mar 19 '16 at 17:19
  • Thanks a lot. Will try to get this implemented. Since i am completely new to access db any pointers would be very helpful. – Santhosh Rao Mar 19 '16 at 17:28
  • There's a decent tutorial [here](http://analysistabs.com/excel-vba/ado-sql-macros-connecting-database/). – Comintern Mar 19 '16 at 17:49
  • If you want to prevent more than one person from running the script at one time, you can do that. Let me know, if you need help with that. Secondly, 2 MB is not big enough anymore to cause a save to be slow; something else must be the reason for the issue. – MikeC Mar 19 '16 at 19:33
  • Initially i thought that this was an issue with my code, but getting to know the limitation of excel, was an eye opener. Yes please help me with this option. I would like to know more details. – Santhosh Rao Mar 19 '16 at 19:59
  • @MikeC Yes please help me with this option. I would like to know more details. – Santhosh Rao Mar 20 '16 at 07:28

1 Answers1

0

It seems possible (not entirely clear) that preventing multiple users from running the macro simultaneously could help prevent the problem. Based on OP's comments above here is the code to achieve that. The code will check Windows processes to see if another instance of this macro is already running. Obviously, this check should be the first thing happening in the OP's script.

Option Explicit

Function RunningInstancesOfThisScript()
    Dim colProcesses
    Dim objProcess
    Dim lScriptCount


    RunningInstancesOfThisScript = 0

    lScriptCount = 0

    ' Get list of running processes using WMI
    Set colProcesses = GetObject("winmgmts:\\.\root\cimv2").ExecQuery("Select * From Win32_Process")

    For Each objProcess in colProcesses
        If (Instr(1, objProcess.Commandline, WScript.ScriptFullName, vbTextCompare) <> 0) Then
            lScriptCount = lScriptCount + 1
        End If
    Next

    RunningInstancesOfThisScript = lScriptCount 
End Function

Function IsThisScriptAlreadyRunning()
    Dim lScriptCount




    lScriptCount = RunningInstancesOfThisScript()

    If (lScriptCount < 1) Then
        ' This should not happen. There should be at least one instance, the current one
        IsThisScriptAlreadyRunning = False
    ElseIf (lScriptCount = 1) Then
        ' The current instance is the only one
        IsThisScriptAlreadyRunning = False
    Else
        IsThisScriptAlreadyRunning = True
    End If
End Function

If (IsThisScriptAlreadyRunning() = True) Then
    MsgBox "Another instance of this script is already running. This instance will now terminate without making any changes. Please try again after a few minutes.", vbExclamation
    WScript.Quit
Else
    MsgBox "There is no other instance of this script currently running. This instance will now proceed and make the changes needed.", vbInformation
End If

Another option is to check if the Excel file is already open. To run the following script, you'd need to replace <FileName> with a real file name.

Option Explicit

Function IsOfficeFileAlreadyOpen(strOfficeFileFullName)
    Dim lPos
    Dim strLockFileFullName



    lPos = InstrRev(strOfficeFileFullName, "\", -1, vbBinaryCompare)
    If (lPos = 0) Then
        ' Only file name has been given, no path specified. Must be in current folder. Good luck!
        strLockFileFullName = "~$" & strOfficeFileFullName
    Else
        strLockFileFullName = Left(strOfficeFileFullName, lPos) & "~$" & Mid(strOfficeFileFullName, lPos + 1)
    End If

    IsOfficeFileAlreadyOpen = CreateObject("Scripting.FileSystemObject").FileExists(strLockFileFullName)
End Function

If (IsOfficeFileAlreadyOpen("<FileName>") = True) Then
    MsgBox "The file '" & <FileName> & "' is already open. Please try again once the file is closed.", vbExclamation
    WScript.Quit
Else
    ' Open the file first
    MsgBox "The file '" & "<FileName>" & "' is available and will be processed.", vbInformation
End If

Both these solutions are susceptible to race conditions.

MikeC
  • 960
  • 1
  • 7
  • 15
  • Note to @Anantha Rao : 2 MB files should not take too long to save in this day and age; digging into the reason for that as a separate exercise could be beneficial. – MikeC Mar 20 '16 at 16:06
  • Thanks a lot for your help. For now have got a issue fixed. – Santhosh Rao Apr 06 '16 at 13:50
  • How did you fix it? It is to everyone's benefit to explain that. – MikeC Apr 06 '16 at 18:22
  • We had Created a new file for each user which was which was programmed to be updated in a central location. This we would merge the details manually. – Santhosh Rao Oct 12 '17 at 11:21