Chuyên đề giải đáp những thắc mắc về code VBA

Liên hệ QC

maytinhvp01

Thành viên thường trực
Tham gia
27/7/13
Bài viết
390
Được thích
179
Mình muốn nhờ giải thich câu lệnh " If Ran.Cells(d, c) > max Then max = Ran.Cells(d, c) "
trong ví du:
Public Function LonNhat(Ran As Range)
Dim max As Double, v As Integer, d As Integer, c As Integer
max = Ran.Cells(1, 1)
For d = 1 To Ran.Rows.Count
For c = 1 To Ran.Columns.Count
If Ran.Cells(d, c) > max Then max = Ran.Cells(d, c)
Next c
Next d
v = Tim(max, Ran)
LonNhat = max
End Function
-------------------------------------------------------
[INFO1]Thông báo:
Vì topic này:
http://www.giaiphapexcel.com/forum/...ải-thích-các-code-đề-nghị-các-bạn-gửi-vào-đây
đã quá dài nên BQT đóng lại.
Nay tôi mở topic mới với cùng chủ đề: GIẢI THÍCH NHỮNG THẮC MẮC VỀ CODE
Các bạn nếu có nhu cầu giải thích code, vui lòng post tại đây nhé
NDU96081631

[/INFO1]
 
Chỉnh sửa lần cuối bởi điều hành viên:
Khi dùng code, người ta luôn luôn tránh tình trạng ngày tháng không thống nhất.
Trước khi ghi dữ liệu, luôn luôn đưa nó về dạng chuẩn. Bạn có hai cách:
1. dùng hàm dateserials để đổi chuỗi thành dạng số - chịu khó tìm, trên diễn đàn có nhiều rồi.
2. dùng dạng chuẩn của CSDL, tức là "yyyy/mm/dd". Khi Excel gặp dữ liệu loại này, nó tự động đổi thành ngày đúng như mong muốn.

Mã:
Sub ThemNgayNghiLe2()
    Dim Parts() As String
    Dim Default
    Default = "01/31/2019,02/04/2019,02/05/2019,02/06/2019,02/07/2019,02/08/2019"
    On Error GoTo NoText
    Parts = Split(Replace(InputBox("Enter the values separated by commas", "List of HOLIDAYS (mm/dd/yyyy)", Default, 10000, 1000), ", ", ","), ",")
    Range("A15:A30").Select
    With Selection
        .ClearContents
        .NumberFormat = "dd/mm/yyyy"
    End With
    For Default = LBound(Parts) To UBound(Parts)
        Parts(Default) = UniversalDate(Parts(Default), "US") ' nếu nhập dạng dd/mm/yyyy thì dùng tham "EU"
    Next Default
    Range("A15").Resize(1 + UBound(Parts)).Cells = Application.Transpose(Parts)
NoText:
End Sub

Function UniversalDate(ByVal d As String, Optional inTyp As String = "US") As String
' function to change date string from dd/mm/yyyy (inTyp="EU"), or mm/dd/yyyy (inTyp="US") to yyyy/mm/dd
Dim x() As String
x = Split(d, "/")
If Len(x(2)) < 4 Then x(2) = CStr(2000 + Val(x2)) ' normalise year
If UCase(inTyp) = "US" Then
UniversalDate = x(2) & "/" & x(0) & "/" & x(1)
Else
UniversalDate = x(2) & "/" & x(1) & "/" & x(0)
End If
End Function

(tôi chỉ mách cho cách giải quyết dữ liệu ngày tháng thôi. Code của bạn có hiệu quả hay không là chuyện khác)
 
Upvote 0
Nếu tôi không lầm thì bạn nên nhập ở dạng "mm/dd/yyyy" như bạn đang làm bây giờ và
Mã:
.NumberFormat = "m/d/yyyy"
Lúc đó mang sang máy nào cũng chuẩn, chả cần thêm code gì cả.

Tôi trình bầy với 2 thiết lập Ba Lan và Việt Nam ở máy tôi. Bạn chạy ở máy bạn xem thế nào.

Khi bạn đã hỏi và có người trả lời thì nên thông báo lại là vấn đề có được giải quyết hay không. "Lặng lẽ" chuồn là không nên.

Nếu trên máy bạn lại khác thì thông báo để tôi biết nhé.
 

File đính kèm

Upvote 0
Nếu tôi không lầm thì bạn nên nhập ở dạng "mm/dd/yyyy" như bạn đang làm bây giờ và
Mã:
.NumberFormat = "m/d/yyyy"
Lúc đó mang sang máy nào cũng chuẩn, chả cần thêm code gì cả.
...
Điểm này tôi đồng ý với bác. VBA luôn luôn mặc định biến đổi ngày theo dạng của Mẽo. Vì vậy nhập ở dạng mm/dd/yyy thì máy nào cũng ra được ngày như nhau cả.

Tôi nghĩ người hỏi bài bị rối (confused) ở chỗ 31/01/2019 vẫn ra giống như 01/31/2019. Cho nên mới phải đem lên đây hỏi.
Câu trả lời là: tuy VBA mặc định dạng mm/dd/yyyy nhưng nếu gặp tháng lớn hơn 12 thì nó tự động hiểu như dạng dd/mm/yyyy

Bác bảo immediate
? #01/31/2019#, #31/01/2019#
sẽ thấy nó in ra cả hai đều là ngày 31 tháng giêng
 
Upvote 0
Bác bảo immediate
? #01/31/2019#, #31/01/2019#
sẽ thấy nó in ra cả hai đều là ngày 31 tháng giêng
Thì thế tôi mới nói là phải nhập ở dạng "mm/dd/yyyy". Nếu muốn nhập 31 tháng Một năm 2019 thì phải nhập 01/31/2019 - dạng "mm/dd/yyyy" như yêu cầu, chứ không nên nhập 31/01/2019 - dạng "dd/mm/yyyy" không như yêu cầu.

Mà người hỏi cũng nhập

"01/31/2019,02/04/2019,02/05/2019,02/06/2019,02/07/2019,02/08/2019"

chứ có nhập

"31/01/2019,02/04/2019,02/05/2019,02/06/2019,02/07/2019,02/08/2019"

đâu.
 
Upvote 0
Thì thế tôi mới nói là phải nhập ở dạng "mm/dd/yyyy". Nếu muốn nhập 31 tháng Một năm 2019 thì phải nhập 01/31/2019 - dạng "mm/dd/yyyy" như yêu cầu, chứ không nên nhập 31/01/2019 - dạng "dd/mm/yyyy" không như yêu cầu.

Mà người hỏi cũng nhập

"01/31/2019,02/04/2019,02/05/2019,02/06/2019,02/07/2019,02/08/2019"

chứ có nhập

"31/01/2019,02/04/2019,02/05/2019,02/06/2019,02/07/2019,02/08/2019"

đâu.
Ở bài #1873 người hỏi bị lủng củng kiểu nhập.

Tại em khó diễn đạt quá. Với code:
Mã:
Sub ThemNgayNghiLe3()
    Dim Parts() As String
    Dim Default
    Default = "31/01/2019,04/02/2019,05/02/2019,06/02/2019,07/02/2019,08/02/2019"
    On Error GoTo NoText
    Parts = Split(Replace(InputBox("Enter the values separated by commas", "List of HOLIDAY", Default, 10000, 1000), ", ", ","), ",")
    Range("A15:A30").Select
    With Selection
        .ClearContents
        .NumberFormat = "dd/mm/yyyy"
    End With
    With Range("A15").Resize(1 + UBound(Parts))
        .Cells = Application.Transpose(Parts)
    End With
NoText:
End Sub
Thì với 31/01/2019 thì nó dạng text, còn lại thì dạng dd/mm/yyyy nhưng lại hiển thị kiểu mm/dd/yyyy ah

Còn khi vào nhập dữ liệu vào box kiểu tháng trước ngày sau thì kết quả ở sheet lại chuẩn kiểu dd/mm/yyyy. Mà em thì muốn kiểu VN.
View attachment 211992
.
31/01/2019 ở dạng text là vì hàm Transpose không tự động chuyển từ dd/mm sang mm/dd được. Và bảng tính không nhận nó là ngày.
04/02/2019 được dịch ra là ngày 2 tháng tư, lên bảng tính bạn định dạng thành ra 02/04/2019
Nếu bạn đặt ở ô B16, hàm =A16+1 thì sẽ thấy là 03/04/2019
 
Upvote 0
Ở bài #1873 người hỏi bị lủng củng kiểu nhập.
Thì thế bài #1872 tôi mới thắc mắc - vì lủng củng ngay từ bài #1871 rồi - vì tôi không hiểu.
Nhìn
Default = "01/31/2019,02/04/2019,02/05/2019,02/06/2019,02/07/2019,02/08/2019"
...
Parts = Split(Replace(InputBox("Enter the values separated by commas", "List of HOLIDAY (mm/dd/yyyy)", Default, 10000, 1000), ", ", ","), ",")

thì là bạn đang hướng dẫn người ta nhập theo dạng mm/dd/yyyy chứ đâu phải như bây giờ bạn viết là
Khi nhập giá trị ngày tháng theo kiểu dd/mm/yyyy vào inputbox

Rõ ràng hướng dẫn cho người khác ở trên trời, à nhầm, ở tiêu đề InputBox, là phải nhập dạng mm/dd/yyyy - List of HOLIDAY (mm/dd/yyyy), và cả ở dưới đất, à nhầm, ở Default, là phải nhập dạng mm/dd/yyyy - "01/31/2019,02/04/2019,02/05/2019,02/06/2019,02/07/2019,02/08/2019". Nhưng tới khi mình nhập thì lại nhập dạng dd/mm/yyyy - Khi nhập giá trị ngày tháng theo kiểu dd/mm/yyyy vào inputbox.

Tuy nhiên do tác giả không giải thích cho tôi sự mâu thuẫn trong cách hành sử của mình nên tôi bỏ qua
Thôi tôi cũng không đi sâu vào vấn đề nữa.

Tôi đề nghị mm/dd/yyyy + .NumberFormat = "m/d/yyyy" là để kết quả luôn hiển theo đúng như thiết lập trên máy hiện hành. Tức hiển thị sao cho đúng như người sử dụng hàng ngày vẫn quen. Bởi nếu dùng code
Mã:
Sub ThemNgayNghiLe2()
    Dim Parts() As String
    Dim Default
    Default = "01/31/2019,02/04/2019,02/05/2019,02/06/2019,02/07/2019,02/08/2019"
    On Error GoTo NoText
    Parts = Split(Replace(InputBox("Enter the values separated by commas", "List of HOLIDAY (" & Format(Date, "Short Date") & ")", Default, 10000, 1000), ", ", ","), ",")
    Range("A15:A30").Select
    With Selection
        .ClearContents
        .NumberFormat = "dd/mm/yyyy"
    End With
    With Range("A15").Resize(1 + UBound(Parts))
        .Cells = Application.Transpose(Parts)
    End With
NoText:
End Sub
thì trên máy tôi kết quả đúng là ngày tháng (định dạng Custom: dd-mm-yyyy) nhưng là
31-01-2019
04-02-2019
05-02-2019
06-02-2019
07-02-2019
08-02-2019

Nó làm cho người dùng hơi bị bất ngờ tuy người ta vẫn hiểu, và không đúng chuẩn Ba Lan. Chuẩn là
2019-01-31
2019-02-04
2019-02-05
2019-02-06
2019-02-07
2019-02-08

Chính vì thế mà tôi yêu sách là phải làm sao trả về đúng ngày tháng. Còn chuyện nó có dạng thư thế nào trên máy hiện hành thì không nên can thiệp. Cứ cứng nhắc là phải nhìn thấy 31/01/2019 là không được. Phải làm sao để anh Việt nhìn thấy 31/01/2019 nhưng cũng tập tin đó, code đó thì anh Ba Lan phải nhìn thấy 2019-01-31, anh Anh cũng phải nhìn thấy như mình hàng ngày vẫn thấy.

Mọi code viết chỉ để cố tình định dạng kết quả theo một dạng cứng nhắc theo tôi là không nên dùng. Chỉ phải trả kết quả đúng là ngày tháng. Còn dạng như thế nào thì để Excel tự xác định dựa trên thiết lập trong CP của máy hiện hành
 
Lần chỉnh sửa cuối:
Upvote 0
Dạ em cảm ơn ah, tại tối muộn mà sáng lại đi trực nên chưa reply and like các Thầy ah! em đang làm cái bảng cho bên kho quỹ tính công bốc xếp, chấm công..... Em đang test các kiểu. em sẽ báo lại sau khi hoàn chỉnh ah!
 
Upvote 0
Mã:
Sub Test()
'
    Dim r1, r2, c1, c2 As Long
    Sheets("Sheet1").Select
    Range("mang1").Select
    Selection(1, 1).Select
    r1 = Application.Selection.Row
    c1 = Application.Selection.Column
    Sheets("Sheet2").Select
    Range("mang2").Select
    Selection(1, 1).Select
    r2 = Application.Selection.Row - r1
    c2 = Application.Selection.Column - c1
    Sheets("Sheet1").Range("mang1").FormulaR1C1 = "=Data!R[r2]C[c2]"
'
End Sub
Các anh cho em hỏi tại dòng code 14: "=Data!R[r2]C[c2]" thì có cách nào đưa biến r2, c2 vào công thức muốn chèn không ạ. Em đưa vào bị lỗi không chạy được.
Mục đích code VBA để chèn công thức từ mang1 ở Sheet 1 lấy dữ liệu tương ứng từ mang2 ở Sheet2 trong khi mảng 2 không cố định vị trí.
Trân trọng cảm ơn!
 
Lần chỉnh sửa cuối:
Upvote 0
Mã:
Sub Test()
'
    Dim r1, r2, c1, c2 As Long
    Sheets("Sheet1").Select
    Range("mang1").Select
    Selection(1, 1).Select
    r1 = Application.Selection.Row
    c1 = Application.Selection.Column
    Sheets("Sheet2").Select
    Range("mang2").Select
    Selection(1, 1).Select
    r2 = Application.Selection.Row - r1
    c2 = Application.Selection.Column - c1
    Sheets("Sheet1").Range("mang1").FormulaR1C1 = "=Data!R[r2]C[c2]"
'
End Sub
Các anh cho em hỏi tại dòng code 14: "=Data!R[r2]C[c2]" thì có cách nào đưa biến r2, c2 vào công thức muốn chèn không ạ. Em đưa vào bị lỗi không chạy được.
Mục đích code VBA để chèn công thức từ mang1 ở Sheet 1 lấy dữ liệu tương ứng từ mang2 ở Sheet2 trong khi mảng 2 không cố định vị trí.
Trân trọng cảm ơn!
"=Data!R[r2]C[c2]" là 1 chuỗi, bạn thu sua lại the này xem sao
"=Data!R[" & r2 & "]C[" & c2 & "]"
 
Upvote 0
Mã:
'Sheets("Sheet1").Range("mang1").FormulaR1C1 = "=Sheet2!R["&r2&"]C["&c2&"]"
Sheets("Sheet1").Range("mang1").FormulaR1C1 = "=Sheet2!R[" & r2 & "]C[" & c2 & "]"
Bạn thay dòng trên bằng dòng dưới là ok. Lỗi là do thiếu dấu phân cách

Hay quá, mình đã làm được rồi, cảm ơn bạn nhiều nhé!
 
Upvote 0
Sub test()
Dim i As Integer
For i = 2 To 36 Step 5
For j = 8 To 38 Step 5
Range("G" & i).Value = "='[03.2019 CROWN.xlsm]Oshidashi Crown'!K$" & j
Next j
Next i
End Sub
nhờ các thầy giúp em xem đoạn code này sai chỗ nào với ạ
Đơn thuần em muốn ở ô:
G2 = K8 của sheet khác
G7= K13
 
Upvote 0
nhờ các thầy giúp em xem đoạn code này sai chỗ nào với ạ
Đơn thuần em muốn ở ô:
G2 = K8 của sheet khác
G7= K13
Bạn dùng 2 vòng lặp ở tình huấn này là không đúng
Mã:
Sub test()
Dim i As Integer
For i = 2 To 36 Step 5
Range("G" & i).Value = "='[03.2019 CROWN.xlsm]Oshidashi Crown'!K$" & i + 6
Next i
End Sub
 
Upvote 0
Bạn dùng 2 vòng lặp ở tình huấn này là không đúng
Mã:
Sub test()
Dim i As Integer
For i = 2 To 36 Step 5
Range("G" & i).Value = "='[03.2019 CROWN.xlsm]Oshidashi Crown'!K$" & i + 6
Next i
End Sub
nếu em muốn cho nó chạy từ cột G đến cột AK thì phải thêm vòng lặp thế nào ạ
 
Upvote 0
Các bác cho em hỏi có lệnh như này thì viết như nào ạ?
Nếu textbox.text = "" thì không không thực hiện chạy sub ( không thực nhập dữ liệu từ button "nhập liệu")
 
Lần chỉnh sửa cuối:
Upvote 0
Bạn dùng 2 vòng lặp ở tình huấn này là không đúng
Mã:
Sub test()
Dim i As Integer
For i = 2 To 36 Step 5
Range("G" & i).Value = "='[03.2019 CROWN.xlsm]Oshidashi Crown'!K$" & i + 6
Next i
End Sub
Anh ạ. Nó vẫn chưa ra kết quả đúng.
Chẳng hạn em muốn ngược lại là:
K9=G3
k14=G8
K19= G13
thì phải làm thế nào ạ. hay tạo 1 cột xong lấy range theo số mình muốn ạ
Lý do có cái này là do em muốn link dữ liệu từ 2 file sang cho nhau ạ
 
Upvote 0
Anh ạ. Nó vẫn chưa ra kết quả đúng.
Chẳng hạn em muốn ngược lại là:
K9=G3
k14=G8
K19= G13
thì phải làm thế nào ạ. hay tạo 1 cột xong lấy range theo số mình muốn ạ
Lý do có cái này là do em muốn link dữ liệu từ 2 file sang cho nhau ạ
Bạn có thể áp dụng code sau, tuy nhiên đã chạy code rồi thì không ai đi làm phương pháp thủ công nữa cả

PHP:
Sub test_CopyData()
  CopyData [k9], [g3], -6, "Oshidashi Crown", "03.2019 CROWN.xlsm", 36, 5, True, False
End Sub
  Function CopyData(Rng1 As Range, _
  Rng2 As Range, _
  istep%, _
  Optional ByVal worksheetStr$ = "Oshidashi Crown", _
  Optional ByVal workbookStr$, _
  Optional ByVal stopLoop% = 36, _
  Optional ByVal stepLoop% = 5, _
  Optional ByVal RowAbsolute As Boolean = True, Optional ByVal ColumnAbsolute As Boolean = False)
    Dim i%
    For i = Rng1.Row To stopLoop Step stepLoop
      Cells(i, Rng1.Column).Formula = "=" & IIf(workbookStr = "", "", "[" & workbookStr & "]") & worksheetStr & "!" & _
      Cells(i + istep, Rng2.Column).Address(RowAbsolute, ColumnAbsolute)
    Next i
  End Function
 
Lần chỉnh sửa cuối:
Upvote 0
Web KT

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

Back
Top Bottom