Nhờ sửa lỗi code không copy y nguyên định dạng format ngày giờ được (1 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

pinklove

Thành viên thường trực
Tham gia
21/1/08
Bài viết
336
Được thích
42
Nhờ các bạn xem giúp mình, dữ liệu mình import vào ở sheet "goc", sau đó code sẽ copy sang sheet "TAM". Nhưng ở khi sang sheet "TAM" cột ngày tháng cứ tự chuyển thành định dạng "tháng/ngày/năm" chứ ko giữ nguyên mặc định như ở sheet "goc" dẫn đến kết quả bị sai lệch.
 

File đính kèm

Nguyên nhân do trong goc không là ngày tháng chuẩn. Theo Excel thì chúng là ngày tháng nhái, là text giả bộ ngày tháng.
 
Upvote 0
Do file gốc xuất ra từ chương trình nó là thế rồi, bạn khắc phục giúp mình với
Nguyên nhân do trong goc không là ngày tháng chuẩn. Theo Excel thì chúng là ngày tháng nhái, là text giả bộ ngày tháng.
Trong trường hợp của bạn thử sửa thành
Mã:
dArr(k, j) = Format(sArr(i, j - 1), "dd/mm/yyyy hh:mm:ss")
Tôi nói là trong trường hợp của bạn vì mở trên máy tôi thì sau khi chạy code thì bên TAM có ngày tháng chuẩn nhưng nếu tôi tự gõ tay thêm ngày tháng chuẩn ở goc, còn các ngày tháng cũ vẫn để nguyên là text thì kết quả bên TAM là ngày tháng chuẩn cho dữ liệu cũ còn những ngày tháng tôi tự gõ chuẩn là ngày tháng bên goc khi sang TAM sẽ lại bị đổi vị trí ngày tháng. Nhưng tôi nghĩ là trên máy bạn khi bạn gõ tay thêm ngày tháng chuẩn thì khi sang TAM nó vẫn đúng, không bị đổi ngày tháng.

Nếu trên máy tôi mà muốn khắc phục để khi tự gõ thêm ngày tháng chuẩn và khi sang TAM vẫn chuẩn thì chỉ còn nước "biến" ngày tháng ở goc thành ngày tháng chuẩn thay vì để như cũ là tet giả bộ ngày tháng. Và để như cũ dArr(k, j) = sArr(i, j - 1)
--------
Bạn chuyển thành ngày tháng chuẩn ở goc như sau: chọ cột H -> thẻ Data -> Tet to column -> Next -> Next -> chọn Date -> chọn DMY -> Finish
 
Lần chỉnh sửa cuối:
Upvote 0
Nguyên nhân do trong goc không là ngày tháng chuẩn. Theo Excel thì chúng là ngày tháng nhái, là text giả bộ ngày tháng.
Trong trường hợp của bạn thử sửa thành
Mã:
dArr(k, j) = Format(sArr(i, j - 1), "dd/mm/yyyy hh:mm:ss")
Tôi nói là trong trường hợp của bạn vì mở trên máy tôi thì sau khi chạy code thì bên TAM có ngày tháng chuẩn nhưng nếu tôi tự gõ tay thêm ngày tháng chuẩn ở goc, còn các ngày tháng cũ vẫn để nguyên là text thì kết quả bên TAM là ngày tháng chuẩn cho dữ liệu cũ còn những ngày tháng tôi tự gõ chuẩn là ngày tháng bên goc khi sang TAM sẽ lại bị đổi vị trí ngày tháng. Nhưng tôi nghĩ là trên máy bạn khi bạn gõ tay thêm ngày tháng chuẩn thì khi sang TAM nó vẫn đúng, không bị đổi ngày tháng.

Nếu trên máy tôi mà muốn khắc phục để khi tự gõ thêm ngày tháng chuẩn và khi sang TAM vẫn chuẩn thì chỉ còn nước "biến" ngày tháng ở goc thành ngày tháng chuẩn thay vì để như cũ là tet giả bộ ngày tháng. Và để như cũ dArr(k, j) = sArr(i, j - 1)
Vẫn không được bạn ạ. Trên máy mình dù mình sửa lại định dạng trong file gốc thì nó vẫn xuất sai. Cái này nếu như ngày lớn hơn 12, tức lớn hơn tháng nso sẽ đúng. Còn ngày nhỏ hơn thì nó sẽ như thế.
 
Upvote 0
Vẫn không được bạn ạ. Trên máy mình dù mình sửa lại định dạng trong file gốc thì nó vẫn xuất sai. Cái này nếu như ngày lớn hơn 12, tức lớn hơn tháng nso sẽ đúng. Còn ngày nhỏ hơn thì nó sẽ như thế.
Nếu bạn chọn sửa ở goc thì phải "ép" nó về ngày tháng chuẩn chứ không chỉ đơn giản là sửa lại định dạng. Về cách "ép" thì tôi có viết thêm ở bài trước.
 
Upvote 0
Chép thay cái cũ
PHP:
Public Sub LDT_tam()
Dim sArr(), dArr() As String, i As Long, j As Long, k As Long
Trên máy tôi khi chỉ sửa như thế thì sau khi chạy code sẽ có ngày tháng nhái. Tức nhìn thì thấy đúng thứ tự ngày tháng năm nhưng thực chất là text, không cộng trừ được. Dữ liệu như thế chỉ nhìn cho đẹp mắt, không tính toán được.

Nói chung dữ liệu gốc nên chuyển về ngày tháng chuẩn. Chả nhẽ cứ lúc lúc lại xoay xở?

Ngoài ra trên máy tôi thì thậm chí 02/12/2019 08:29:26 nhìn cũng không là ngày tháng. Trên máy tôi nhìn ngày tháng phải là 2019-12-02 08:29:26

Mà nếu chỉ làm cho mình, sống với tiêu chí một mình một hòn đảo thì thế nào cũng được. Nhưng nếu là sống ở thời đại hợp tác toàn cầu, làm chuẩn cho dù mở ở máy nào, với thiết lập nào cũng đúng thì chỉ còn nước chuyển dữ liệu gốc về dạng chuẩn.
 
Lần chỉnh sửa cuối:
Upvote 0
1575278874950.png
Mình đã sửa theo cách ép của bạn đây mà vẫn ko được. hic
 
Upvote 0
Mình đã sửa theo cách ép của bạn đây mà vẫn ko được. hic
Không phải "ép" như thế. Tôi đã viết rõ mà
Về cách "ép" thì tôi có viết thêm ở bài trước.
Bài trước
Bạn chuyển thành ngày tháng chuẩn ở goc như sau: chọ cột H -> thẻ Data -> Tet to column -> Next -> Next -> chọn Date -> chọn DMY -> Finish


Cách Format chỉ là thử "đối phó" nhưng tôi cũng đã viết là nó không dùng được vì trên máy tôi khi nhập ngày tháng chuẩn ở goc thì sang TAM nó bị đảo ngày tháng. Ngoài ra nếu ở các cột khác ở góc có SỐ thì SỐ đó sẽ bị chuyển thành dạng ngày tháng ................................. nhái. Vì thế tôi mới khuyên là "ép" ngày tháng ở goc về dạng chuẩn.
 
Lần chỉnh sửa cuối:
Upvote 0
À, bạn edit bài làm mình ko để ý. Để mình thử.
 
Upvote 0
Trên mgáy tôi khi chỉ sửa như thế thì sau khi chạy code sẽ có ngày tháng nhái. Tức nhìn thì thấy đúng thứ tự ngày tháng năm nhưng thực chất là text, không cộng trừ được. Dữ liệu như thế chỉ nhìn cho đẹp mắt, không tính toán được.
Em làm theo đúng yêu cầu chủ topic thôi anh. Tức là kết quả cứ giống sheet "goc" là được.

Còn công thức của chủ thớt đang làm ở cột kế bên đó chưa chắc đúng (cho dù làm ngay với dữ liệu ở sheet "goc"). Bài này có nhiều rồi, chủ thớt tự tìm thôi.
 
Upvote 0
Có hai cách cho bạn:

Cách 1: (Nhanh hơn nhưng phải xử lý một lần duy nhất)
Sửa dữ liệu ngày Sheet "goc" trước: bằng cách chạy Sub ChangeFormatDateWrong một lần duy nhất khi "goc" có dữ liệu.

Cách 2: (Tốt nhất)
Chuẩn hóa ngày tháng khi xử lý dữ liệu bằng cách sửa đổi trong Code:

---------------------
PHP:
If sArr(i, j - 1) Like "*/*/*:*:*" Then
    dArr(k, j) = FormatDateWrong(sArr(i, j - 1), "$2/$1/$3 $4")
Else
    dArr(k, j) = sArr(i, j - 1)
End If

Đoạn này chính là chuyển đổi vị trí ngày tháng năm: "$2/$1/$3 $4"
Bạn chỉ cần thay đổi vị trí $x với nhau, nếu phần mềm một ngày nào đó lại vô tình đổi vị trí ngày tháng ngược lại.
Hoặc Window có mặc định định dạng của ngày tháng năm là khác.
------------------

PHP:
Sub ChangeFormatDateWrong()
  Dim LR&, R As Range, Arr$(), T$
  Set R = ThisWorkbook.Sheets("goc").Range("H2")
  LR = R(Rows.Count - R.Row, 1).End(3).Row - R.Row + 1
  If LR > Application.Columns.Count Then LR = Application.Columns.Count
  T = VBA.Join(Application.Transpose(R.Resize(LR).Value), ",")
  T = FormatDateWrong(T, "$2/$1/$3 $4")
  Arr = Split(T, ",")
  R.Resize(LR).Value = Application.Transpose(Arr)
  Set R = Nothing: Erase Arr
  FormatDateWrong "", Terminate:=True
End Sub
Function FormatDateWrong(ByVal Text As String, _
                Optional ByVal AreaMove$ = "$2/$1/$3 $4", _
                Optional ByVal Terminate As Boolean = 0) As String
  Static RE As Object
  If RE Is Nothing Then
    Set RE = CreateObject("VBScript.RegExp")
  Else
    If Terminate Then Set RE = Nothing: Exit Function
  End If
  With RE
    .Global = True
    .Pattern = "(\d{1,4})\/(\d{1,4})\/(\d{1,4}) (\d{1,2}:\d{1,2}:\d{1,2})"
    FormatDateWrong = .Replace(Text, AreaMove)
  End With
End Function
 
Lần chỉnh sửa cuối:
Upvote 0
Ngoài ra trên máy tôi thì thậm chí 02/12/2019 08:29:26 nhìn cũng không là ngày tháng. Trên máy tôi nhìn ngày tháng phải là 2019-12-02 08:29:26
Nếu có chỗ nào chưa giống như sheet "goc" thì cần chỉnh cột ngày đó trở về nguyên trạng "General". Hiện tại chủ thớt đang định dạng custom gì đó.
 
Upvote 0
Không phải "ép" như thế. Tôi đã viết rõ mà

Bài trước



Cách Format chỉ là thử "đối phó" nhưng tôi cũng đã viết là nó không dùng được vì trên máy tôi khi nhập ngày tháng chuẩn ở goc thì sang TAM nó bị đảo ngày tháng. Ngoài ra nếu ở các cột khác ở góc có SỐ thì SỐ đó sẽ bị chuyển thành dạng ngày tháng ................................. nhái. Vì thế tôi mới khuyên là "ép" ngày tháng ở goc về dạng chuẩn.
Vẫn ko được, sheet TAM của mình vẫn bị chuyển kiểu mm/dd/yyyy. Có cách nào nó copy y nguyên bên sheet goc sang ko ạ.
 
Upvote 0
Nếu có chỗ nào chưa giống như sheet "goc" thì cần chỉnh cột ngày đó trở về nguyên trạng "General". Hiện tại chủ thớt đang định dạng custom gì đó.
Cái này tôi biết. Nhưng chuyển về General thì ở goc vẫn là text giả bộ ngày tháng và sau khi chạy code với chỉnh sửa của bạn thì ở TAM có ngày tháng nhái. Tức cũng là text giả bộ ngày tháng. Tuy ngày tháng không bị đổi chỗ nhưng ngày tháng kiểu đó không tính toán được.
 
Upvote 0
Cái này tôi biết. Nhưng chuyển về General thì ở goc vẫn là text giả bộ ngày tháng và sau khi chạy code với chỉnh sửa của bạn thì ở TAM có ngày tháng nhái. Tức cũng là text giả bộ ngày tháng. Tuy ngày tháng không bị đổi chỗ nhưng ngày tháng kiểu đó không tính toán được.
Thôi thì chỉnh luôn dòng này:
PHP:
.Range("A5:J500").Clear
Em đã nêu ở trên là chỉ chỉnh theo đúng yêu cầu chủ thớt: " copy y nguyên bên sheet goc sang ", chứ không giải quyết việc khác.
 
Upvote 0
Vẫn ko được, sheet TAM của mình vẫn bị chuyển kiểu mm/dd/yyyy. Có cách nào nó copy y nguyên bên sheet goc sang ko ạ.
Không được là thế nào?
Sau khi dùng text to column thì bạn hãy nhập công thức ở đâu đó
Mã:
=H16+1
Nếu có lỗi #VALUE! thì có nghĩa là bạn chuyển CHƯA THÀNH CÔNG. Và lúc đó đượng nhiên vẫn là TEXT và khi sang TAM thì bị đổi ngày tháng.

Nếu bạn muốn y nguyên như goc thì làm theo befaint. Nhưng tôi ý thức là bên TAM sẽ chỉ là TEXT giả bộ ngày tháng, không tính toán được.
 
Upvote 0
Cái này tôi biết. Nhưng chuyển về General thì ở goc vẫn là text giả bộ ngày tháng và sau khi chạy code với chỉnh sửa của bạn thì ở TAM có ngày tháng nhái. Tức cũng là text giả bộ ngày tháng. Tuy ngày tháng không bị đổi chỗ nhưng ngày tháng kiểu đó không tính toán được.
Mình không hề định dạng mà ở sheet TAM nó tự định dạng cột I dang custom. chỉnh lại cũng ko được.
Có hai cách cho bạn:

Cách 1: (Nhanh hơn nhưng phải xử lý một lần duy nhất)
Sửa dữ liệu ngày Sheet "goc" trước: bằng cách chạy Sub ChangeFormatDateWrong một lần duy nhất khi "goc" có dữ liệu.

Cách 2: (Tốt nhất)
Chuẩn hóa ngày tháng khi xử lý dữ liệu bằng cách sửa đổi trong Code:
Mình làm theo cách của bạn cũng ko được luôn. Không hiểu do setup gì trên máy không? Nhưng trên máy DATE mình set theo chuẩn rồi.
 
Upvote 0
Mình bó tay rồi ạ. Làm theo mọi cách các bạn nói vẫn bị. Các bạn giúp mình sửa hẳn trong file với, để xem ko biết mình sai chỗ nào nữa ko
 
Upvote 0
Mình không hề định dạng mà ở sheet TAM nó tự định dạng cột I dang custom. chỉnh lại cũng ko được.

Mình làm theo cách của bạn cũng ko được luôn. Không hiểu do setup gì trên máy không? Nhưng trên máy DATE mình set theo chuẩn rồi.

Tôi chịu thôi!

Để giải thích cho bạn hiểu một tí.
1. Trong Excel phải chuyển ngày dạng Text thành Date của Excel để tính toán, khi tính toán để lấy ra ngày tháng năm, gồm các hàm Day, Month, Year
2. Nếu dữ nguyên là Text trong File của bạn chỉ cần bạn để CSTR(sArr(i, j)) là được.
Mã:
If sArr(i, j - 1) Like "*/*/*:*:*" Then
    dArr(k, j) = CSTR(sArr(i, j - 1))
Else
    dArr(k, j) = sArr(i, j - 1)
End If

Hoặc là:
Dim dArr() As String

Đừng trót dại lấy hàm Mid, Left, Right để tìm ngày tháng, phức tạp lắm nhé bạn.
 
Upvote 0
1575281452657.png
Sửa kiểu nào nó cũng thành thế này ạ
 
Upvote 0
1575281948265.png
Khi em import file gốc có ngày lớn hơn tháng thì nó trả về đúng kiểu em cần. Em up lên đây 2 file gốc của em các bác xem giúp. Cái T11 là cái cuối tháng nên nó đúng. Cái T12 đầu tháng nó sai.
 

File đính kèm

Upvote 0
Bạn thử thay thế Sub LDT_tam này vào. Lý do đi loằn ngoằn, lòng vòng, là do bạn đặt câu hỏi.
Vì sao không vào thẳng ý muốn của bạn trong bài viết.

PHP:
Public Sub LDT_tam()
  Dim sArr(), i As Long, j As Long, k As Long
  With Sheets("goc")
    sArr = .Range(.[A2], .[AC65536].End(xlUp)).Value
  End With
  ReDim dArr(1 To UBound(sArr, 1), 1 To 12)
  With Sheets("TAM")
    For i = 1 To UBound(sArr, 1)
      If sArr(i, 14) = "" Then
        If sArr(i, 15) = "" Then
          If sArr(i, 29) <> "" Then
            k = k + 1
            dArr(k, 1) = k
            For j = 2 To 10
              If sArr(i, j - 1) Like "*/*/*:*:*" Then
                dArr(k, j) = CDate(sArr(i, j - 1))
                dArr(k, 11) = ((CDate(.[L4].Value2) - CDate(sArr(i, j - 1))) * 1440) \ 1
                dArr(k, 12) = IIf(dArr(k, 11) > 240, "KH" & ChrW(212) & "NG ", "") & ChrW(272) & ChrW(7840) & "T"
              Else
                dArr(k, j) = sArr(i, j - 1)
              End If
            Next j
          End If
        End If
      End If
    Next i
    .Range("A5:L500").ClearContents
    If k Then
      .Range("A5").Resize(k, 12) = dArr
    End If
  End With
End Sub
 
Upvote 0
Mình bó tay rồi ạ. Làm theo mọi cách các bạn nói vẫn bị.
Sao bạn không dùng Text to column? Sao không chuyển dữ lựu gốc thành ngày tháng chuẩn?

Lưu ý: khi bạn chỉ có ngày tháng không có thời gian thì Text to column thành công ngay. Khi có ngày tháng và thời gian thì phải kiểm tra trong Control Panel và: chọn Việt Nam với dd/MM/yyyy. Sau đó dùng Text to column thành công. Ít ra là trên máy tôi.
 
Upvote 0
Để khỏi thành nói phét thì tôi đã làm như video đính kèm. Tôi không dùng bất cứ code nào cả. Chỉ Text to column thôi.


Trong tập tin video bạn thấy tôi thao tác lần lượt như sau:

- trước tiên kiểm tra thấy dữ liệu cột H ở goc được căn trái, công thức ở I1 trả về #VALUE!.

Tức là text giả bộ ngày tháng

- tôi chạy code của bạn

- tôi kiểm tra kết quả ở TAM thì thấy ngày tháng bị đổi chỗ.

- tôi chọn cột H trong goc và dùng Text to column

- kiểm tra thấy dữ liệu cột H ở goc được căn trái, công thức ở I1 trả về #VALUE!. Tức vẫn là

text giả bộ ngày tháng

- tuy nhiên tôi vẫn thử chạy code và kiểm tra kết quả ở TAM thì vẫn thấy ngày tháng bị đổi chỗ.

- tôi vào Control Panel thì rõ ràng thiết lập đang của Ba Lan.

- tôi chuyển sang chọn Việt Nam với dd/MM/rrrr - r là rok (Ba Lan) = y là year (English)

- kiểm tra thấy I1 không còn lỗi nhưng cột H vẫn bị canh trái, tức chưa chuẩn 100%.

- tôi lại chọn cột H và dùng Text to column.

- kiểm tra thấy dữ liệu cột H đã được canh trái.

- tôi chạy code rồi kiểm tra TAM. Bây giờ ngày tháng đã đúng chỗ.

Một khi ngày tháng đã chuẩn theo cách hiểu của Excel thì bây giờ có chọn gì trong Control

Panel thì Excel cũng sẽ hiển thị ngày tháng chuẩn theo thiết lập được chọn. Tức tôi lại chuyển

trong CP về Ba Lan. Trên máy tôi sẽ là 2019-12-02 ... Nhưng nếu tôi gửi tập tin cho ông ngoại

quốc là bạn thì bạn sẽ thấy 02/12/2019 ...

Nếu chỉ có ngày tháng mà không có thời gian thì tôi dùng Text to Column thành công ngay mà

không cần thay đổi thiết lập trong CP sang Việt Nam.
 
Upvote 0
Nhờ các bạn xem giúp mình, dữ liệu mình import vào ở sheet "goc", sau đó code sẽ copy sang sheet "TAM". Nhưng ở khi sang sheet "TAM" cột ngày tháng cứ tự chuyển thành định dạng "tháng/ngày/năm" chứ ko giữ nguyên mặc định như ở sheet "goc" dẫn đến kết quả bị sai lệch.
Bạn 2 Nick hay sao mà File 2 bài viết của 2 Nick ở 2 nơi lại rập khuông nhau.
Vào Link này định dạng ngày giờ tải File về dùng thử.
 
Lần chỉnh sửa cuối:
Upvote 0
Theo mình cách tốt nhất cho chủ bài đăng là tách từ nguồn (Trang 'Goc') thành 2 cột ở trang đích ('Tam'); 1 cột là MM/DD/yyyy & cột nữa là 'HH:mm:cc'
Thêm nữa cột 'MM/dd/yyyy' ta có thể định dạng thành 'DD/MM/yyyy' cho quen mắt

Tác giả bài đăng không nên 'muốn gì được nấy' cho cột chứa dữ liệu về ngày-tháng-năm; nhất là trong thời kỳ hội nhập!
 
Upvote 0
Bạn 2 Nick hay sao mà File 2 bài viết của 2 Nick ở 2 nơi lại rập khuông nhau.
Vào Link này định dạng ngày giờ tải File về dùng thử.
Cảm ơn các bạn đã giúp đỡ , hôm qua liên hoan cơ quan nên về ko biết gì để check nữa. Hôm nay e sẽ kiểm tra lại ạ.
Em chỉ dùng 1 nick này và chỉ đăng bài này ở đây thôi ạ
 
Upvote 0
Bạn thử thay thế Sub LDT_tam này vào. Lý do đi loằn ngoằn, lòng vòng, là do bạn đặt câu hỏi.
Vì sao không vào thẳng ý muốn của bạn trong bài viết.

PHP:
Public Sub LDT_tam()
  Dim sArr(), i As Long, j As Long, k As Long
  With Sheets("goc")
    sArr = .Range(.[A2], .[AC65536].End(xlUp)).Value
  End With
  ReDim dArr(1 To UBound(sArr, 1), 1 To 12)
  With Sheets("TAM")
    For i = 1 To UBound(sArr, 1)
      If sArr(i, 14) = "" Then
        If sArr(i, 15) = "" Then
          If sArr(i, 29) <> "" Then
            k = k + 1
            dArr(k, 1) = k
            For j = 2 To 10
              If sArr(i, j - 1) Like "*/*/*:*:*" Then
                dArr(k, j) = CDate(sArr(i, j - 1))
                dArr(k, 11) = ((CDate(.[L4].Value2) - CDate(sArr(i, j - 1))) * 1440) \ 1
                dArr(k, 12) = IIf(dArr(k, 11) > 240, "KH" & ChrW(212) & "NG ", "") & ChrW(272) & ChrW(7840) & "T"
              Else
                dArr(k, j) = sArr(i, j - 1)
              End If
            Next j
          End If
        End If
      End If
    Next i
    .Range("A5:L500").ClearContents
    If k Then
      .Range("A5").Resize(k, 12) = dArr
    End If
  End With
End Sub
Chân thành cảm ơn bạn, mình đã sửa theo code này và ok rồi ạ
 
Upvote 0

Bài viết mới nhất

Back
Top Bottom