Làm sao để khi gõ số 1 tại 1 ô, sẽ tự động ra kết quả 1/2/2012 ngay tại ô đó?

Liên hệ QC

bebo021999

Thành viên gạo cội
Tham gia
26/1/11
Bài viết
5,837
Được thích
8,567
Donate (Momo)
Donate
Giới tính
Nam
Nghề nghiệp
GPE
Các anh chị em cho hỏi trường hợp này:
A1=2012
A2=2
Tại A3: Khi nhập số từ 1-31, VD nhập số 9, sẽ hiển thị thành 9/2/2012?

Dùng công thức hay chức năng có sẵn trên Excel được không?
Tôi đã nghĩ phương án dùng name, VD, NAME có tên là 1 =DAT(A1,A2,1),....,NAME có tên là 31...
nhưng không cho phép đặt tên bằng số.

Nếu không, nhờ ACE cho 1 đoạn code được không?

Xin cảm ơn,
 
Nếu chỉ có vậy thì định dạng đi! Gõ vào Type là: 0"/2/2012"
 
Upvote 0
Nếu chỉ có vậy thì định dạng đi! Gõ vào Type là: 0"/2/2012"

Vẫn chưa đạt:
Thứ nhất, thực sự giá trị ô đó vẫn là 1. Mình muốn giá trị thực là 9/2/2012 = 40948
Thứ hai, định dạng này không tự thay đổi theo giá trị tại ô A1 và A2.

Làm bằng VBA đi?
 
Upvote 0
Vẫn chưa đạt:
Thứ nhất, thực sự giá trị ô đó vẫn là 1. Mình muốn giá trị thực là 9/2/2012 = 40948
Thứ hai, định dạng này không tự thay đổi theo giá trị tại ô A1 và A2.

Làm bằng VBA đi?

Nói vậy chứ khó bẫy lỗi lắm, kể cả VBA, làm sao mà gõ vào nó hiểu đúng ngày trong tháng của năm đó chứ? Ví dụ mình giới hạn tháng là 30 ngày nêu có 31 thì sao? Còn tháng 2 có 28 thôi, max thì 29 vậy gõ 30 thì sao? thôi thì cứ định dạng "d/m/yyyy" đi, rồi gõ 9/2 vào là OK.
 
Upvote 0
Vẫn chưa đạt:
Thứ nhất, thực sự giá trị ô đó vẫn là 1. Mình muốn giá trị thực là 9/2/2012 = 40948
Thứ hai, định dạng này không tự thay đổi theo giá trị tại ô A1 và A2.

Làm bằng VBA đi?
Thử Code "củ chuối" này đi, tháng 2/2012 mà gõ số 30 hay 31 thì nó nhảy qua tháng 3 ráng chịu.
PHP:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, [A3]) Is Nothing And Target.Value <= 31 Then
    Target = DateSerial([A1], [A2], Target)
End If
End Sub
 

File đính kèm

  • GPE.xls
    24.5 KB · Đọc: 20
Upvote 0
Nói vậy chứ khó bẫy lỗi lắm, kể cả VBA, làm sao mà gõ vào nó hiểu đúng ngày trong tháng của năm đó chứ? Ví dụ mình giới hạn tháng là 30 ngày nêu có 31 thì sao? Còn tháng 2 có 28 thôi, max thì 29 vậy gõ 30 thì sao? thôi thì cứ định dạng "d/m/yyyy" đi, rồi gõ 9/2 vào là OK.
Sao không được nhỉ?
Đại khái là làm cái sự kiện "after Enter" gì gì đó, lấy cell.value ghép vào hàm DATE với tham số ô A1 và A2.
Không biết hiểu vậy có đúng không?
 
Upvote 0
Sao không được nhỉ?
Đại khái là làm cái sự kiện "after Enter" gì gì đó, lấy cell.value ghép vào hàm DATE với tham số ô A1 và A2.
Không biết hiểu vậy có đúng không?

Vậy coi bài của Ba Tê đi, dạo này Bác này viết tốt rồi đó! hihihi
 
Upvote 0
Hic, trình độ Excel em còn kém lắm ạ, chưa dám thử lửa.
Chỉ sợ học xong VBA lại thành Gã Chết Tiệt ( Cheettit Young Man) thì toi!̣
Đâu dễ trở thành chết tiệt thế.
Vả lại cứ trông Dauthivan, trungvdb, ... công thức cũng chưa giỏi mà đã dám học VBA, đang hỏi đến mảng và Dic rồi
Lại trông hoamattroicoi, cũng đã thực hành thành công mảng và Dic

Chưa nói tới Cò Già, 3 tháng thành cao thủ VBA!
 
Upvote 0
Cám ơn bác Bate.
1- Không có cách nào cho nó báo lỗi nếu ngày 30/2/2012 à bác?
2- Nếu muốn áp dụng cho 1 vùng nhập liệu, VD:A3:A100 thì sửa code thế nào?
 
Upvote 0
Cám ơn bác Bate.
1- Không có cách nào cho nó báo lỗi nếu ngày 30/2/2012 à bác?
2- Nếu muốn áp dụng cho 1 vùng nhập liệu, VD:A3:A100 thì sửa code thế nào?
- Có thể vận dụng báo lỗi bằng cách so sánh số tháng của ô A2 và ô A3 sau khi nhập liệu.
- Áp dụng cho một vùng là sao, Ô A1 và A2 là cố định phải không?
 
Upvote 0
- Có thể vận dụng báo lỗi bằng cách so sánh số tháng của ô A2 và ô A3 sau khi nhập liệu.
- Áp dụng cho một vùng là sao, Ô A1 và A2 là cố định phải không?
Vâng đúng như vậy. A1 và A2 là năm và tháng hiện hành. Mục đích của em là cho việc nhập liệu được đơn giản.
Nhân tiện hỏi thêm, nếu không cần ô A1 và A2, chỉ cần gõ ngày (VD: 9) là tự hiểu 9/2/2012 luôn thì sao? Nếu được vậy thì tốt quá.
Nhu cầu giản tiện công việc nhập liệu này là có thực trong thực tế.
 
Upvote 0
Vâng đúng như vậy. A1 và A2 là năm và tháng hiện hành. Mục đích của em là cho việc nhập liệu được đơn giản.
Nhân tiện hỏi thêm, nếu không cần ô A1 và A2, chỉ cần gõ ngày (VD: 9) là tự hiểu 9/2/2012 luôn thì sao? Nếu được vậy thì tốt quá.
Nhu cầu giản tiện công việc nhập liệu này là có thực trong thực tế.
thì bebo sửa lại đoạn này
PHP:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, [A3]) Is Nothing And Target.Value <= 31 Then
    Target = DateSerial(Year(Now()), Month(Now()), Target)
    End If
End Sub
nhưng có điều không xóa được ô a3 đâu nhé
 
Lần chỉnh sửa cuối:
Upvote 0
Vâng đúng như vậy. A1 và A2 là năm và tháng hiện hành. Mục đích của em là cho việc nhập liệu được đơn giản.
Nhân tiện hỏi thêm, nếu không cần ô A1 và A2, chỉ cần gõ ngày (VD: 9) là tự hiểu 9/2/2012 luôn thì sao? Nếu được vậy thì tốt quá.
Nhu cầu giản tiện công việc nhập liệu này là có thực trong thực tế.
File này vùng nhập liệu là A3:A100, nhập ngày không có trong tháng báo lỗi, không cần ô A1 và A2, (Lấy tháng năm hiện hành theo máy tính)
PHP:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim Tem
If Not Intersect(Target, [A3:A100]) Is Nothing _
And Target <> "" And Target.Value <= 31 Then
Tem = Target.Value
    Target = DateSerial(Year(Date), Month(Date), Target)
        If Month(Target) > Month(Date) Then
            MsgBox "Thang " & Month(Date) & " khong co ngay " & Day(Tem) + 1
            Target.ClearContents
        End If
End If
End Sub
 

File đính kèm

  • GPE1.rar
    8 KB · Đọc: 7
Lần chỉnh sửa cuối:
Upvote 0
Vâng đúng như vậy. A1 và A2 là năm và tháng hiện hành. Mục đích của em là cho việc nhập liệu được đơn giản.
Nhân tiện hỏi thêm, nếu không cần ô A1 và A2, chỉ cần gõ ngày (VD: 9) là tự hiểu 9/2/2012 luôn thì sao? Nếu được vậy thì tốt quá.
Nhu cầu giản tiện công việc nhập liệu này là có thực trong thực tế.
Ngứa mắt quá!
Làm sơ qua cho chú đây:
PHP:
Private Sub Worksheet_Change(ByVal Target As Range)
  Dim tmp As Long, lMonth As Long, lYear As Long
  On Error GoTo ExitSub
  If Not Intersect(Range("A3:A100"), Target) Is Nothing Then
    Application.EnableEvents = False
    lYear = Range("A1").Value
    lMonth = Range("A2").Value
    tmp = DateSerial(lYear, lMonth, Target.Value)
    If Day(tmp) = Target.Value Then
      With Target
        .NumberFormat = "dd/mm/yyyy"
        .Value = tmp
      End With
    Else
      MsgBox "Ngày không hop le!"
      Target.ClearContents
    End If
    Application.EnableEvents = True
  End If
ExitSub:
  Application.EnableEvents = True
End Sub
Còn phải cải tiến thêm nữa mới "ngon"
----------------
Các bạn viết code nên lưu ý chuyện quan trọng: Bất cứ code nào viết trên sự kiện Change mà thay đổi trực tiếp trên Target thì BẮT BUỘC phải có câu Application.EnableEvents = False ở đầu code và Application.EnableEvents = True ở cuối code, nếu không sẽ có lỗi đáng tiếc xảy ra
 
Lần chỉnh sửa cuối:
Upvote 0
Cám ơn bác Bate.
1- Không có cách nào cho nó báo lỗi nếu ngày 30/2/2012 à bác?
2- Nếu muốn áp dụng cho 1 vùng nhập liệu, VD:A3:A100 thì sửa code thế nào?
Nếu muốn áp dụng cho 1 vùng nhập liệu, VD:A3:A100 thì sửa code thế này
PHP:
Private Sub Worksheet_Change(ByVal Target As Range)
   If Not Intersect(Range("A3:A100"), Target) Is Nothing And Target.Value <= 31 Then
         Cells(Target.Row, 1).Value = DateSerial(Year(Now()), Month(Now()), Target)
         Cells(Target.Row, 1).NumberFormat = "dd/mm/yyyy"
   End If
End Sub
 
Upvote 0
Loay hoay "giăng bẫy" nãy giờ, bây giờ xem lại thấy mọi người sắp lên tận cung trăng rồi. Ẹc ẹc...
Thêm một tham khảo cho yêu cầu ban đầu của bác bebo:
PHP:
Private Sub Worksheet_Change(ByVal Target As Range)
    Application.EnableEvents = False
    If Target.Address = "$A$3" And Target.Count = 1 Then
        If WorksheetFunction.IsNumber([A3]) Then
            If Abs([A3]) > 31 Then GoTo Err
            [A3] = DateSerial([A1], [A2], [A3])
            If Month([A3]) <> [A2] Then GoTo Err
        Else
Err:        MsgBox "Nhap ngay khong hop le"
            [A3].ClearContents: [A3].Select
        End If
    End If
    Application.EnableEvents = True
End Sub
Điều kiện đúng là phải nhập năm, tháng vào các ô A1, A2. Giăng bẫy khắp nơi nhưng vẫn chưa bắt hết giặc...
 

File đính kèm

  • Nhap ngay.rar
    8.8 KB · Đọc: 4
Upvote 0
Lần chỉnh sửa cuối:
Upvote 0
anh có thể bẫy lỗi theo năm nhuận hay năm không nhuận
PHP:
Function namnhuan(Nam As Integer) As Boolean
If (((Nam Mod 4 = 0) And (Nam Mod 100 <> 0)) Or (Nam Mod 400 = 0)) Then
    namnhuan = True
Else
    namnhuan = False
    End If
End Function
nếu năm nhuận thì mình cho tháng 2 max là 29
còn năm không nhuận cho tháng 2 max là 28
những trường hợp khác đã mặc định hết rồi.
tôi không rành VBA cho lắm nên viết còn hơi Lờ tờ mờ
 
Upvote 0
Dạ, em biết điều đó, nhưng đọc trong hướng dẫn về IsNumeric thấy có cái này nên lại ngại:

Bây giờ nghĩ lại thấy dùng IsNumeric cũng chẳng ảnh hưởng gì.
Chính xác là thế! Với dữ liệu dạng Date, hàm IsNumeric cho kết quả = FALSE
Vì thế để dùng cho chắc ăn, ta chuyển format cell sang General là được rồi
Làm bài này ở mức tổng quát nhé
PHP:
Private Sub Worksheet_Change(ByVal Target As Range)
  Dim tmp As Long, lMonth As Long, lYear As Long, lR As Long
  Dim tmpArr(1 To 1, 1 To 1), sArray, tRng As Range
  On Error Resume Next
  If Not Intersect(Range("A3:A100"), Target) Is Nothing Then
    Application.EnableEvents = False
    Set tRng = Intersect(Range("A3:A100"), Target)
    tRng.NumberFormat = "General"
    tmpArr(1, 1) = Target(1, 1).Value
    sArray = tRng.Value
    If Not IsArray(sArray) Then sArray = tmpArr
    lYear = Range("A1").Value
    lMonth = Range("A2").Value
    For lR = 1 To UBound(sArray, 1)
      If IsNumeric(sArray(lR, 1)) Then
        tmp = DateSerial(lYear, lMonth, CLng(sArray(lR, 1)))
        If Day(tmp) = CLng(sArray(lR, 1)) Then
          sArray(lR, 1) = tmp
        Else
          sArray(lR, 1) = vbNullString
        End If
      Else
        sArray(lR, 1) = vbNullString
      End If
    Next
    tRng.NumberFormat = "dd/mm/yyyy"
    tRng.Value = sArray
    Application.EnableEvents = True
  End If
End Sub
Hoặc cách khác, dùng CLng
PHP:
Private Sub Worksheet_Change(ByVal Target As Range)
  Dim tmpDate As Long, lMonth As Long, lYear As Long, lR As Long, tmpDay As Long
  Dim tmpArr(1 To 1, 1 To 1), sArray, tRng As Range
  On Error Resume Next
  If Not Intersect(Range("A3:A100"), Target) Is Nothing Then
    Application.EnableEvents = False
    Set tRng = Intersect(Range("A3:A100"), Target)
    tRng.NumberFormat = "General"
    tmpArr(1, 1) = Target(1, 1).Value
    sArray = tRng.Value
    If Not IsArray(sArray) Then sArray = tmpArr
    lYear = Range("A1").Value
    lMonth = Range("A2").Value
    For lR = 1 To UBound(sArray, 1)
      tmpDay = CLng(sArray(lR, 1))
      If tmpDay Then
        tmpDate = DateSerial(lYear, lMonth, tmpDay)
        If Day(tmpDate) = tmpDay Then
          sArray(lR, 1) = tmpDate
        Else
          sArray(lR, 1) = vbNullString
        End If
      Else
        sArray(lR, 1) = vbNullString
      End If
    Next
    tRng.NumberFormat = "dd/mm/yyyy"
    tRng.Value = sArray
    Application.EnableEvents = True
  End If
End Sub
- Code dùng mảng
- Cho phép copy từ nơi khác paste vào luôn
Ẹc... Ẹc...
 
Lần chỉnh sửa cuối:
Upvote 0
Web KT
Back
Top Bottom