2016-12-23 8 views
0

おかげで、Excel VBAの時間の問題

私は以下のVBAコードに問題があります。おそらく単純なものでしょう。

私は午前23時29分

に午後11時30分、それがが自動変化として時間を入力した場合、私は2330年のように入力した場合、それが必要として、それは午後11時30分に変更されます。

なぜ私は23:30と入力すると23:29に変わるのですか?それはいつものことから、午前23時30分

おかげ

Private Sub Worksheet_Change(ByVal Target As Excel.Range) 
    Dim xStr As String 
    Dim xVal As String 
    Set rng1 = Range("J:J") 
    Set rng2 = Range("P:P") 
    Set rng3 = Range("S:S") 
     On Error GoTo EndMacro 
    If Application.Intersect(Target, Union(rng1, rng2, rng3)) Is Nothing Then Exit Sub 
    If Target.Count > 1 Then Exit Sub 
    If Target.Value = "" Then Exit Sub 
    If Target.Row < 5 Then Exit Sub 
    Application.EnableEvents = False 
    With Target 
     If Not .HasFormula Then 
      Target.Value = Replace(Target.Value, ";", ":") 
      Target.Value = Left(Target.Value, 5) 
      xVal = .Value 
      Select Case Len(xVal) 
       Case 1 ' e.g., 1 = 00:01 AM 
        xStr = "00:0" & xVal 
       Case 2 ' e.g., 12 = 00:12 AM 
        xStr = "00:" & xVal 
       Case 3 ' e.g., 735 = 07:35 AM 
        xStr = "0" & Left(xVal, 1) & ":" & Right(xVal, 2) 
       Case 4 ' e.g., 1234 = 12:34 
        xStr = Left(xVal, 2) & ":" & Right(xVal, 2) 
       Case 5 ' e.g., 12:45 = 12:45 
        xStr = Left(xVal, 2) & Mid(xVal, 2, 1) & Right(xVal, 2) 
       Case Else 
        Err.Raise 0 
      End Select 
      .Value = Format(TimeValue(xStr), "hh:mm") 
     End If 
    End With 
    Application.EnableEvents = True 
    Exit Sub 
EndMacro: 
    Application.EnableEvents = True 
End Sub 
+0

「変更」はいつですか?あなたはそれを見るとき、またはコードのどこかでシートに? – mountainclimber

答えて

1

これは、Excelが時間フィールドを1日の端数として処理するためです。例えば

:= 1

  • 12時間

    • 24時間= 0.5
    • 6時間=あなたのケースで0.25

    :23h30 = 0,979166666 ...

    ただし、最初の5文字しか取得できません:Left(Target.Value, 5) ' "0.979"

    そして、この新しい値(0.979)を現在の値としてセルTarget.Value = Left(Target.Value, 5)に渡します。

    だからラインxStr = Left(xVal, 2) & Mid(xVal, 2, 1) & Right(xVal, 2)に、どのようなあなたのコードが実際にやっていることです:あなたが参加したときに、次のように

    Left(0.979, 2) ' -> "0."

    Mid(xVal, 2, 1) ' -> "."

    Right(xVal, 2) ' -> "79"

    ので、結果は次のとおりです。

    "0." & "." & "79" = "0..79"

    "0..79"は、セルの有効な値ではありません。次にエラーが発生し、関数は0.97923:29の値を保持して終了します。

    私の提案では、セルの値が既に1より小さい場合は変更しないでください。それはすでにそれが時間であることを示しているからです。 xVal = Left(Target.Value, 5)

  • アルター次のように "ケース5" の条件:完全なコードは次のようになりますxStr = Format(Target.Value, "hh:mm")
  • Target.Value = Left(Target.Value, 5)
  • が直接XVALの値を割り当てます。

    1. 行を削除します。
      Private Sub Worksheet_Change(ByVal Target As Excel.Range) 
          Dim xStr As String 
          Dim xVal As String 
          Set rng1 = Range("J:J") 
          Set rng2 = Range("P:P") 
          Set rng3 = Range("S:S") 
          On Error GoTo EndMacro 
      
          If Application.Intersect(Target, Union(rng1, rng2, rng3)) Is Nothing Then Exit Sub 
          If Target.Count > 1 Then Exit Sub 
          If Target.Value = "" Then Exit Sub 
          If Target.Row < 5 Then Exit Sub 
          Application.EnableEvents = False 
          With Target 
           If Not .HasFormula Then 
            Target.Value = Replace(Target.Value, ";", ":") 
            xVal = Left(Target.Value, 5) ' CHANGED! 
            Select Case Len(xVal) 
             Case 1 ' e.g., 1 = 00:01 AM 
              xStr = "00:0" & xVal 
             Case 2 ' e.g., 12 = 00:12 AM 
              xStr = "00:" & xVal 
             Case 3 ' e.g., 735 = 07:35 AM 
              xStr = "0" & Left(xVal, 1) & ":" & Right(xVal, 2) 
             Case 4 ' e.g., 1234 = 12:34 
              xStr = Left(xVal, 2) & ":" & Right(xVal, 2) 
             Case 5 ' e.g., 12:45 = 12:45 
              xStr = Format(Target.Value, "hh:mm") ' CHANGED! 
             Case Else 
              Err.Raise 0 
            End Select 
            .Value = Format(TimeValue(xStr), "hh:mm") ' CHANGED! 
           End If 
          End With 
          Application.EnableEvents = True 
          Exit Sub 
      EndMacro: 
          Application.EnableEvents = True 
      End Sub 
      
  • +0

    ありがとうございます。 – jynxy

    0

    あなたが日付を間違った方向に物事をやろうとしているようだとして残り、日付をフォーマットする方法Formatステートメントを使用することですが、推奨すべきです。あなたは文字列として日付/時刻を操作したい場合は

    しかし、あなたのコードにいくつかの変更を行う必要があり、ちょうど試験後の3行:いっそ

    If Not .HasFormula Then 
         .Value = Replace(.Text, ";", ":") ' <-- use .Text 
         .Value = Left(.Text, 5)   ' <-- 
         xVal = .Text      ' <-- 
    

    かは、直接割り当てますXVAL:一方

    If Not .HasFormula Then 
         xVal = Left(Replace(.Text, ";", ":"), 5) ' <-- 
    

    、あなたは.Valueで、通常は数として符号化され、その後、あなたが自然につながる左端の5桁の日付を切り捨てたエンコードされた日付を、してきたものをいくつかの不正確さ。