1

ワークブックを開いたときに実行されるコードがあり、フォームを使用して、共有ディレクトリがマップされているドライブをユーザーが選択するように要求します。

これは、ワークブックが VBA コードを使用してデータを取得し、この共有ディレクトリにある共有ワークブックに保存するためですが、ローカル ドライブはユーザーによって変更されるため、ローカル ドライブを選択する必要があります。

私が遭遇した問題は、ユーザーが複数の共有ディレクトリをコンピューターにマップしているため、複数のドライブがある場合に発生します...例: 1 つのディレクトリがドライブ G: にあり、もう 1 つのディレクトリが X: にあります。

ワークブックが存在する共有ディレクトリのドライブを選択する場合、問題はありません。ただし、別の共有ディレクトリのドライブを誤って選択すると、コードがハングします。

正しいドライブが選択されていることを確認するループ設定があります... IE: A: (私の例では存在しないドライブ) を選択した場合、コードは、間違ったドライブを選択したことを通知し、プロンプトを表示します。それらをもう一度。

ただし、別の共有ディレクトリが選択されたときにエラーが発生するのではなく、コードがハングするだけです。

以下のコードでは、シート 1 のセル AD3 に true または false が含まれています (サブの先頭で false に設定されます)。Module6.PipelineRefresh がエラーを引き起こさなくなるため、正しいドライブを選択した場合は true に設定されます (このサブルーチンは共有ドライブでワークブックを開こうとします...選択したドライブが正しくない場合、明らかにエラーが返されます)。

コードは以下のとおりです。

Do While Sheet1.Range("ad3") = False
    On Error Resume Next
        Call Module6.PipelineRefresh  '~~ I'm guessing the code hangs here.  Instead of returning an error immediately, as it would if they simply chose a non-existant drive, it appears to get stuck trying to open the workbook, even though it's not located in the shared directory they've selected.
    If Err.Number = 0 Then
        Sheet1.Range("ad3") = True
        Err.Clear
    Else
        MsgBox "Invalid Network Drive."
        DriverSelectForm.Show
        Err.Clear
    End If
Loop

誰かがタイマーを実装する方法を知っていて、しばらくしてからコードをシャットダウンできるようになれば、それは素晴らしいことです。

あるいは、このエラーを回避する方法を知っていれば、それも素晴らしいことです!

コメントに従って編集:

Module6.PipelineRefreshこれはハングする特定のコードです。(DriverSelectForm上に表示) は、セル o1 の値を選択したドライブ文字列 (つまり: X:) に修正します。

Dim xlo As New Excel.Application
Dim xlw As New Excel.Workbook
Dim xlz As String
xlz = Sheet1.Range("o1").Value & "\Region Planning\Created Pipeline.xlsx"
Dim WS As Worksheet
Dim PT As PivotTable

Application.DisplayAlerts = False
Set xlw = xlo.Workbooks.Open(xlz)
Application.DisplayAlerts = True

注:上記のように、ユーザーが存在しないディレクトリを選択すると、ファイルを開くことができないため、上記のコードはすぐにエラーを返します...選択したドライブに共有ディレクトリがマップされている場合(しかし、それは間違ったディレクトリです) 、コードがハングし、エラーが返されないように見えます。

4

2 に答える 2

2

問題を回避することで、自分の質問に答えました。ユーザーが正しいドライブ文字を選択したことを確認する代わりに、CreatObject関数を使用してドライブ名に関連付けられたドライブ文字を見つけています (ドライブ名は変更されないため)。

このコード例:

Dim objDrv      As Object
Dim DriveLtr      As String

For Each objDrv In CreateObject("Scripting.FileSystemObject").Drives
    If objDrv.ShareName = "Shared Drive Name" Then
        DriveLtr = objDrv.DriveLetter
    End If
Next

If Not DriveLtr = "" Then
    MsgBox DriveLtr & ":"
Else
    MsgBox "Not Found"
End If
Set objDrv = Nothing
于 2013-05-13T14:00:50.960 に答える
1

タイマーで一部のコードを停止するソリューション。コードはモジュールに配置する必要があります。

Private m_stop As Boolean
Sub stop_timer(p_start_time As Variant)
  Application.OnTime p_start_time, "stop_loop"
End Sub
Sub signal_timer(p_start_time As Variant)
  Application.OnTime p_start_time, "signal_in_loop"
End Sub
Sub test_loop()
  Dim v_cntr As Long
  m_stop = False
  v_cntr = 0
  stop_timer Now + TimeValue("00:00:05")
  signal_in_loop
  While Not m_stop
    v_cntr = v_cntr + 1
    DoEvents
  Wend
  Debug.Print "Counter:", v_cntr
End Sub
Sub stop_loop()
  m_stop = True
End Sub
Sub signal_in_loop()
  Debug.Print "timer:", Timer
  If Not m_stop Then
    signal_timer Now + TimeValue("00:00:01")
  End If
End Sub

出力:

timer:         50191.92 
timer:         50192 
timer:         50193 
timer:         50194 
timer:         50195 
timer:         50196 
Counter:       67062 
timer:         50197.05 

m_stop はループを制御します。DoEvents は、stop_loop や signal_in_loop などのイベント ハンドラーを遅延プロシージャとして呼び出します。

于 2014-10-29T11:03:14.040 に答える