title: Wait for Shell to finish, then format cells - synchronously execute a command
body: <p>I have an executable that I call using the shell command:</p>
  
  <pre><code>Shell (ThisWorkbook.Path &amp; "\ProcessData.exe")
  </code></pre>
  
  <p>The executable does some computations, then exports results back to Excel.  I want to be able to change the format of the results AFTER they are exported.</p>
  
  <p>In other words, i need the Shell command first to WAIT until the executable finishes its task, exports the data, and THEN do the next commands to format.</p>
  
  <p>I tried the <code>Shellandwait()</code>, but without much luck.</p>
  
  <p>I had:</p>
  
  <pre><code>Sub Test()
  
  ShellandWait (ThisWorkbook.Path &amp; "\ProcessData.exe")
  
  'Additional lines to format cells as needed
  
  End Sub
  </code></pre>
  
  <p>Unfortunately, still, formatting takes place first before the executable finishes.</p>
  
  <p>Just for reference, here was my full code using ShellandWait</p>
  
  <pre><code>' Start the indicated program and wait for it
  ' to finish, hiding while we wait.
  
  
  Private Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Long) As Long
  Private Declare Function WaitForSingleObject Lib "kernel32.dll" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
  Private Declare Function OpenProcess Lib "kernel32.dll" (ByVal dwDesiredAccessas As Long, ByVal bInheritHandle As Long, ByVal dwProcId As Long) As Long
  Private Const INFINITE = &amp;HFFFF
  
  
  Private Sub ShellAndWait(ByVal program_name As String)
  Dim process_id As Long
  Dim process_handle As Long
  
  ' Start the program.
  On Error GoTo ShellError
  process_id = Shell(program_name)
  On Error GoTo 0
  
  ' Wait for the program to finish.
  ' Get the process handle.
  process_handle = OpenProcess(SYNCHRONIZE, 0, process_id)
  If process_handle &lt;&gt; 0 Then
  WaitForSingleObject process_handle, INFINITE
  CloseHandle process_handle
  End If
  
  Exit Sub
  
  ShellError:
  MsgBox "Error starting task " &amp; _
  txtProgram.Text &amp; vbCrLf &amp; _
  Err.Description, vbOKOnly Or vbExclamation, _
  "Error"
  
  End Sub
  
  Sub ProcessData()
  
    ShellAndWait (ThisWorkbook.Path &amp; "\Datacleanup.exe")
  
    Range("A2").Select
      Range(Selection, Selection.End(xlToRight)).Select
      Range(Selection, Selection.End(xlDown)).Select
      With Selection
          .HorizontalAlignment = xlLeft
          .VerticalAlignment = xlTop
          .WrapText = True
          .Orientation = 0
          .AddIndent = False
          .IndentLevel = 0
          .ShrinkToFit = False
          .ReadingOrder = xlContext
          .MergeCells = False
      End With
      Selection.Borders(xlDiagonalDown).LineStyle = xlNone
      Selection.Borders(xlDiagonalUp).LineStyle = xlNone
  End Sub
  </code></pre>