Dùng Code nào để cho ra kết quả là tỷ giá gần nhất của 1 ngày (1 người xem)

  • Thread starter Thread starter cadafi
  • Ngày gửi Ngày gửi
Liên hệ QC

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

cadafi

Hành động từ trái tim
Administrator
Tham gia
27/5/07
Bài viết
4,297
Được thích
11,386
Donate (Paypal)
Donate
Giới tính
Nam
Nghề nghiệp
Business Man
Chào các anh chị,
Em có một vấn đề sau:
Em có một danh mục tỉ giá theo ngày như sau:
|
A​
|
B​
|
C​
|
D​
|
1​
|
CURY ID​
|
RATE DATE​
|
BASE CURY ID​
|
CURY RATE​
|
2​
|USD|
01/01/2008​
|VND|
16590​
|
3​
|DKK|
01/01/2008​
|USD|
5.7​
|
4​
|USD|
12/09/2008​
|VND|
17890​
|
5​
|USD|
14/09/2008​
|VND|
17891​
|
6​
|USD|
16/09/2008​
|VND|
17892​
|
7​
|USD|
18/09/2008​
|VND|
17893​
|
8​
|USD|
20/09/2008​
|VND|
17894​
|
9​
|USD|
22/09/2008​
|VND|
17895​
|
10​
|USD|
24/09/2008​
|VND|
17896​
|
11​
|USD|
26/09/2008​
|VND|
17897​
|
12​
|USD|
28/09/2008​
|VND|
17898​
|
13​
|USD|
30/09/2008​
|VND|
17899​
|
14​
|USD|
02/10/2008​
|VND|
17900​
|
15​
|USD|
04/10/2008​
|VND|
17901​
|
16​
|USD|
06/10/2008​
|VND|
17902​
|
17​
|USD|
08/10/2008​
|VND|
17903​
|
18​
|USD|
10/10/2008​
|VND|
17904​
|
19​
|USD|
12/10/2008​
|VND|
17905​
|<== Lấy tỷ giá này
20​
|USD|
14/10/2008​
|VND|
17906​
|
21​
|USD|
16/10/2008​
|VND|
17907​
|
22​
|USD|
18/10/2008​
|VND|
17908​
|
23​
|USD|
20/10/2008​
|VND|
17909​
|
24​
|USD|
22/10/2008​
|VND|
17910​
|
25​
|USD|
24/10/2008​
|VND|
17911​
|
26​
|USD|
26/10/2008​
|VND|
17912​
|
27​
|USD|
28/10/2008​
|VND|
17913​
|
Khi ta chọn một ngày bất kỳ, macro sẽ chọn ra tỷ giá của ngày gần nhất (Ngày tỷ giá <= ngày tham chiếu)
Ví dụ: Khi ta chọn ngày 13/10/2008 thì ngày gần nhất trong danh mục là ngày 12/10/2008 ==> lấy tỷ giá 17.905 điền vào 1 ô nào đó.
Xin các anh chị xem file đính kèm.
Xin các anh chị cho em giải pháp bằng VBA càng gọn càng tốt! Em xin cảm ơn!
 

File đính kèm

Lần chỉnh sửa cuối:
Cái này bác Kiệt có trêu mọi người không vậy?
Bác có thể dùng Vlookup, hoặc hàm gì đó xác định cận gần nhất (cận trên - cận dưới) của ngày rồi Offset sang phải là xong ngay?
Thân.
 
Upvote 0
Cái này bác Kiệt có trêu mọi người không vậy?
Bác có thể dùng Vlookup, hoặc hàm gì đó xác định cận gần nhất (cận trên - cận dưới) của ngày rồi Offset sang phải là xong ngay?
Thân.
Cách dùng công thức thì mình biết rồi! Mình cần giải pháp bằng VBA (không dùng Name, không dùng công thức excel)! Gán thẳng giá trị tìm được vào 1 ô nào đó!
Mình đã thử điền công thức mảng bằng VBA vào ô đó dùng FormulaArray nhưng không được. Vì hình như FormulaArray chỉ chấp nhận công thức với cách nhập R1C1, mà nhìn vào đó thì bó tay! Mình cần giải pháp/thuật giải bằng VBA.
 
Lần chỉnh sửa cuối:
Upvote 0
Đơn giản vậy thôi!
PHP:
Function curyR(vung As Range, ngay As Date)
For Each cel In vung.Offset(, 1).Resize(, 1)
If cel <= ngay Then
temp = cel
End If
Next
curyR = vung.Find(temp).Offset(, 2).Resize(, 1)
End Function
PHP:
=curyR(A2:D55,H1)
Thân.
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Cái này sẽ nhanh hơn nè

PHP:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
 If Not Intersect(Target, [h1]) Is Nothing Then
    Dim Rng As Range, sRng As Range:                        Dim jJ As Integer
    
    Set Rng = Range([b1], [b1].End(xlDown))
    Rng.NumberFormat = "MM/DD/YYYY"
    Set sRng = Rng.Find(Format(Target.Value, "Short Date"), , xlFormulas, xlWhole)
    If sRng Is Nothing Then
        Do
            jJ = jJ + 1:                        If jJ = Rng.Rows.Count Then Exit Sub
            Set sRng = Rng.Find(Format(Target.Value + jJ, "Short Date"), , xlFormulas)
            If Not sRng Is Nothing Then
                [h2].Value = sRng.Offset(-1, 2):            Exit Do
            End If
        Loop
    Else
        [h2].Value = sRng.Offset(, 2)
    End If
 End If
End Sub
 
Upvote 0
Dùng VBA, viết truy cập Sheet như database (giống A-Excel của Tuân đó) như sau:

SELECT TOP 1 CURY_RATE FROM tb_CurencyRateHistory WHERE RATE_DATE <= '10/13/2008' ORDER BY RATE_DATE DESC

P/S: Tên trường (cột), tên bảng (Sheet) không nên viết hoa như ở trên vì khi viết SQL sẽ ko phân biệt được với từ khóa của SQL (thường được viết hoa)
 
Upvote 0
Về phần tìm kiếm thì không có vấn đề, nhưng tôi đang thắc mắc 1 chuyện... ví dụ: nếu gõ vào khung tìm kiếm ngày 1/1/2008 thì ta sẽ lấy tỉ giá nào? Lấy cái đầu tiên tìm thấy (16590) hay lấy cái nhỏ nhất tìm thấy (5.7) ---> Tôi để ý thấy cột A có USD và DKK, cột C có VND và USD ---> Sao không thấy nói gì đến chuyện này nhỉ?
 
Upvote 0
PHP:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
 If Not Intersect(Target, [h1]) Is Nothing Then
    Dim Rng As Range, sRng As Range:                        Dim jJ As Integer
    
    Set Rng = Range([b1], [b1].End(xlDown))
    Rng.NumberFormat = "MM/DD/YYYY"
    Set sRng = Rng.Find(Format(Target.Value, "Short Date"), , xlFormulas, xlWhole)
    If sRng Is Nothing Then
        Do
            jJ = jJ + 1:                        If jJ = Rng.Rows.Count Then Exit Sub
            Set sRng = Rng.Find(Format(Target.Value + jJ, "Short Date"), , xlFormulas)
            If Not sRng Is Nothing Then
                [h2].Value = sRng.Offset(-1, 2):            Exit Do
            End If
        Loop
    Else
        [h2].Value = sRng.Offset(, 2)
    End If
 End If
End Sub

Tìm kiếm Date bằng Sub thì không có vấn đề, tuy nhiên tìm kiếm Date bằng UDF lại chẳng hề dễ chút nào.
Không tin thử xem bác ạ.
Không hiểu sao Find, Lookup Function lại không hoạt động trong VBA với Date.

To Po_Pikachu :Sao mình thấy UDF này không chạy nhỉ. Có thể post File lên được không??

--CV--
 
Upvote 0
Lần chỉnh sửa cuối:
Upvote 0
Thử kiểm tra lỗi xem nó bị do đâu?
Tìm trong VBA và thử xem bạn có bị dòng "Option Explicit" không?
Sao code này chạy được code kia thì không?
Thân.
 
Upvote 0
Tôi thì down file của Po về chỉ báo lổi có mỗi 1 chổ duy nhất, đó là chưa khai báo biến (cel và Temp)---> Còn lại chạy ngon lành
 
Upvote 0
Nếu lỗi do chưa khai báo biến thì bạn bỏ chọn mục Require Variable Declaration (VBA -> Tools -> thẻ Editor -> bỏ chọn Require Variable Declaration)
Vậy thì ổn!
Thân.
 
Upvote 0
Khai báo lại các biến đầy đủ,lỗi vẫn hoàn lỗi.
Thế mới mệt chứ.
Các bác test thử hộ hàm này xem có lỗi không ?? Máy em là bó tay rồi.

PHP:
Function TyGia(Ngay As Date, MangNgay As Range, MangTyGia As Range) As Long
    On Error Resume Next
    Application.Volatile (False)
    If MangNgay.Columns.Count * MangNgay.Columns.Count <> 1 Then Exit Function
    If Ngay = "" Then Exit Function
    Dim i As Long
    i = WorksheetFunction.Match(Ngay, MangNgay, 1)
    TyGia = MangTyGia(i)
End Function

--CV--
 
Upvote 0
Lần sau bạn nhớ đem code lên ngay từ đầu nha!
PHP:
Function TyGia(Ngay As Date, MangNgay As Range, MangTyGia As Range)
    Application.Volatile (False)
    If MangNgay.Columns.Count * MangNgay.Columns.Count <> 1 Then Exit Function
    If Ngay = 0 Then Exit Function
    Dim i As Long
    i = WorksheetFunction.Match(CDbl(Ngay), MangNgay, 1)
    TyGia = MangTyGia(i)
End Function
Thân.
 
Upvote 0
Lần sau bạn nhớ đem code lên ngay từ đầu nha!
PHP:
Function TyGia(Ngay As Date, MangNgay As Range, MangTyGia As Range)
    Application.Volatile (False)
    If MangNgay.Columns.Count * MangNgay.Columns.Count <> 1 Then Exit Function
    If Ngay = 0 Then Exit Function
    Dim i As Long
    i = WorksheetFunction.Match(CDbl(Ngay), MangNgay, 1)
    TyGia = MangTyGia(i)
End Function
Thân.


Mình làm code này rồi, tuy nhiên khi test lại bị lỗi nên không dám đưa lên (Bây giờ vẫn còn lỗi). Vì vậy không biết do máy hay do Code nữa.
Nhưng khi thử code của bác thấy cũng lỗi, mà người khác dùng vẫn OK, thiết nghĩ chắc do máy của mình.
Vì vậy mạo muội post lên, hy vọng code chạy được. Không biết có chạy được không.
Chứ không có ý gì cả.

Tuyệt vời đấy, chỉ mỗi cái CDbl mà khác hẳn.
Cảm ơn nhiều

Tuy nhiên UDF của bác vẫn chưa chạy được trên máy em.
-------------------------------------------------------
Code trên có thể sửa thành :
PHP:
Function TyGia(Ngay As Double, MangNgay As Range, MangTyGia As Range) As Long
    On Error Resume Next
    Application.Volatile (False)
    If MangNgay.Columns.Count * MangNgay.Columns.Count <> 1 Then Exit Function
    Dim i As Long
    i = WorksheetFunction.Match(Ngay, MangNgay, 1)
    TyGia = MangTyGia(i)
End Function

--CV--
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Về phần tìm kiếm thì không có vấn đề, nhưng tôi đang thắc mắc 1 chuyện... ví dụ: nếu gõ vào khung tìm kiếm ngày 1/1/2008 thì ta sẽ lấy tỉ giá nào? Lấy cái đầu tiên tìm thấy (16590) hay lấy cái nhỏ nhất tìm thấy (5.7) ---> Tôi để ý thấy cột A có USD và DKK, cột C có VND và USD ---> Sao không thấy nói gì đến chuyện này nhỉ?
Đúng như vậy anh ndu ơi! Do sơ sót nên em viết thiếu. Khi tìm tỷ giá thì phải tìm theo loại tiền tệ (cột A) và theo ngày tỷ giá (cột B). Đại khái viết hàm với ba tham số sau:
[Loại tiền tệ], [Đồng tiền làm cơ sở quy đổi], [ngày lấy tỷ giá]
Trong trường hợp của em:
[Loại tiền tệ]:|USD
[Đồng tiền làm cơ sở quy đổi]:|VND
[ngày lấy tỷ giá]:|12/10/2008
 
Upvote 0
Em có viết đoạn code này, nhưng thấy nó sao sao ấy! Mong các anh chị cải tiến giúp. Có cách nào rút ngắn For..next lại không! Vì như code bên dưới sẽ quét hết cả vùng dữ liệu.
[highlight=vb]
Sub GetExcRate()
Dim mDate As Date
Dim CuryID As String, BaseCuryID As String
Dim rngExcRate As Range, ExcRate As Double
Dim mRng As Range, MaxRow As Long, iR As Long
'---------------------------------------------------
mDate = Sheet1.[C1]
CuryID = Sheet1.[C2]
BaseCuryID = Sheet1.[C3]
MaxRow = Sheet1.[A65536].End(xlUp).Row
'---------------------------------------------------
Set rngExcRate = Sheet1.[C4]
Set mRng = Sheet1.Range("A6:D" & MaxRow)
'---------------------------------------------------
'Sort Du lieu truoc khi tim:
mRng.Sort Key1:=Range("A7"), Order1:=xlAscending, Key2:=Range("B7") _
, Order2:=xlAscending, Header:=xlGuess, OrderCustom:=1, MatchCase:= _
False, Orientation:=xlTopToBottom, DataOption1:=xlSortNormal, DataOption2 _
:=xlSortNormal
'---------------------------------------------------
For iR = 7 To MaxRow
With Sheet1
If (.Cells(iR, "A") = CuryID) And (.Cells(iR, "B") <= mDate) And (.Cells(iR, "C") = BaseCuryID) Then
ExcRate = .Cells(iR, "D").Value
End If
End With
Next iR
rngExcRate.Value = ExcRate
End Sub
[/highlight]

Em nghĩ đến việc AutoFilter theo CuryID, BaseCuryID và RateDate<=mDate rồi dùng For .. Next để quét vùng copy đã filter thôi. Nhưng chưa biết viết code làm sao để excel hiểu chỉ quét vùng đã AutoFilter.
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Em nghĩ đến việc AutoFilter theo CuryID, BaseCuryID và RateDate<=mDate rồi dùng For .. Next để quét vùng copy đã filter thôi. Nhưng chưa biết viết code làm sao để excel hiểu chỉ quét vùng đã AutoFilter.
Thì ...
For Each Clls in Range(....).SpecialCells(12)....
Quét qua các cell có thuộc tính Visible = True ---> Có vấn đề gì chứ
 
Upvote 0
Thì ...
For Each Clls in Range(....).SpecialCells(12)....
Quét qua các cell có thuộc tính Visible = True ---> Có vấn đề gì chứ
Hehe! Cái vụ SpecialCells mà em quên hoài! Cảm ơn anh ndu!
Tuy nhiên, không biết khi AutoFilter nó lại không ra như ý muốn, có lẽ điều kiện ngày có vấn đề, mong anh sửa giúp
[highlight=vb]
Sub GetExcRate1()
Dim mDate As Date
Dim CuryID As String, BaseCuryID As String
Dim rngExcRate As Range, ExcRate As Double
Dim mRng As Range, mCell As Range, MaxRow As Long, iR As Long
'---------------------------------------------------
mDate = Sheet1.[C1] 'Sheet1.[C1] đã được format dạng ngày "dd/mm/yyyy"
CuryID = Sheet1.[C2]
BaseCuryID = Sheet1.[C3]
MaxRow = Sheet1.[A65536].End(xlUp).Row
'---------------------------------------------------
Set rngExcRate = Sheet1.[C4]
Set mRng = Sheet1.Range("A6:D" & MaxRow)
'---------------------------------------------------
'Kiểm tra xem sheet có Autofilter chưa:
If Sheet1.AutoFilterMode = True Then Sheet1.AutoFilterMode = False
'---------------------------------------------------
'Autofilter:
mRng.AutoFilter Field:=1, Criteria1:=CuryID
mRng.AutoFilter Field:=2, Criteria1:="<=" & mDate
mRng.AutoFilter Field:=3, Criteria1:=BaseCuryID
'---------------------------------------------------
For Each mCell In Sheet1.Range("A6:A" & MaxRow).SpecialCells(12)
If (mCell = CuryID) And (mCell.Offset(, 1) <= mDate) And (mCell.Offset(, 2) = BaseCuryID) Then
ExcRate = mCell.Offset(, 3).Value
End If
Next mCell
rngExcRate.Value = ExcRate
End Sub
[/highlight]
 

File đính kèm

Upvote 0
Hehe! Cái vụ SpecialCells mà em quên hoài! Cảm ơn anh ndu!
Tuy nhiên, không biết khi AutoFilter nó lại không ra như ý muốn, có lẽ điều kiện ngày có vấn đề, mong anh sửa giúp
[highlight=vb]
Sub GetExcRate1()
Dim mDate As Date
Dim CuryID As String, BaseCuryID As String
Dim rngExcRate As Range, ExcRate As Double
Dim mRng As Range, mCell As Range, MaxRow As Long, iR As Long
'---------------------------------------------------
mDate = Sheet1.[C1] 'Sheet1.[C1] đã được format dạng ngày "dd/mm/yyyy"
CuryID = Sheet1.[C2]
BaseCuryID = Sheet1.[C3]
MaxRow = Sheet1.[A65536].End(xlUp).Row
'---------------------------------------------------
Set rngExcRate = Sheet1.[C4]
Set mRng = Sheet1.Range("A6:D" & MaxRow)
'---------------------------------------------------
'Kiểm tra xem sheet có Autofilter chưa:
If Sheet1.AutoFilterMode = True Then Sheet1.AutoFilterMode = False
'---------------------------------------------------
'Autofilter:
mRng.AutoFilter Field:=1, Criteria1:=CuryID
mRng.AutoFilter Field:=2, Criteria1:="<=" & mDate
mRng.AutoFilter Field:=3, Criteria1:=BaseCuryID
'---------------------------------------------------
For Each mCell In Sheet1.Range("A6:A" & MaxRow).SpecialCells(12)
If (mCell = CuryID) And (mCell.Offset(, 1) <= mDate) And (mCell.Offset(, 2) = BaseCuryID) Then
ExcRate = mCell.Offset(, 3).Value
End If
Next mCell
rngExcRate.Value = ExcRate
End Sub
[/highlight]
Thử sửa
Criteria1:="<=" & mDate
thành
Criteria1:="<=" & CDbl(mDate)
Vụ này đã nói mấy lần rồi mà
 
Upvote 0
Upvote 0
Em mới nghĩ ra thêm một bước nữa không dùng For...next gì cả.
Nếu ta sort dữ liệu trước, sau đó autofilter và lồng hai cái specialcells vào nhau, đại khái là
Specialcells(xlCellTypeVisible).Specialcells(xlCellTypeLastCell).
[highlight=vb]
Sub GetExcRate1()
Dim mDate As Date
Dim CuryID As String, BaseCuryID As String
Dim rngExcRate As Range
Dim mRng As Range, mCell As Range, MaxRow As Long, iR As Long
'---------------------------------------------------
mDate = DateSerial(Year(Sheet1.[C1]), Month(Sheet1.[C1]), Day(Sheet1.[C1]))
CuryID = Sheet1.[C2]
BaseCuryID = Sheet1.[C3]
MaxRow = Sheet1.[A65536].End(xlUp).Row
'---------------------------------------------------
Set rngExcRate = Sheet1.[C4]
Set mRng = Sheet1.Range("A6:D" & MaxRow)
'---------------------------------------------------
'Kiem tra xem da autofilter chua:
If Sheet1.AutoFilterMode = True Then Sheet1.AutoFilterMode = False
'Sort Du lieu truoc khi tim:
mRng.Sort Key1:=Range("A7"), Order1:=xlAscending, Key2:=Range("B7") _
, Order2:=xlAscending, Header:=xlGuess, OrderCustom:=1, MatchCase:= _
False, Orientation:=xlTopToBottom, DataOption1:=xlSortNormal, DataOption2 _
:=xlSortNormal
'---------------------------------------------------
'Autofilter:
mRng.AutoFilter Field:=1, Criteria1:=CuryID
mRng.AutoFilter Field:=2, Criteria1:="<=" & CDbl(mDate)
mRng.AutoFilter Field:=3, Criteria1:=BaseCuryID
'---------------------------------------------------
rngExcRate.Value = Sheet1.Range("A6:A" & MaxRow).SpecialCells(12).SpecialCells(xlCellTypeLastCell).Value
End Sub
[/highlight]
 
Upvote 0
Em mới nghĩ ra thêm một bước nữa không dùng For...next gì cả.
Nếu ta sort dữ liệu trước, sau đó autofilter và lồng hai cái specialcells vào nhau, đại khái là
Specialcells(xlCellTypeVisible).Specialcells(xlCellTypeLastCell).
[highlight=vb]
Sub GetExcRate1()
Dim mDate As Date
Dim CuryID As String, BaseCuryID As String
Dim rngExcRate As Range
Dim mRng As Range, mCell As Range, MaxRow As Long, iR As Long
'---------------------------------------------------
mDate = DateSerial(Year(Sheet1.[C1]), Month(Sheet1.[C1]), Day(Sheet1.[C1]))
CuryID = Sheet1.[C2]
BaseCuryID = Sheet1.[C3]
MaxRow = Sheet1.[A65536].End(xlUp).Row
'---------------------------------------------------
Set rngExcRate = Sheet1.[C4]
Set mRng = Sheet1.Range("A6:D" & MaxRow)
'---------------------------------------------------
'Kiem tra xem da autofilter chua:
If Sheet1.AutoFilterMode = True Then Sheet1.AutoFilterMode = False
'Sort Du lieu truoc khi tim:
mRng.Sort Key1:=Range("A7"), Order1:=xlAscending, Key2:=Range("B7") _
, Order2:=xlAscending, Header:=xlGuess, OrderCustom:=1, MatchCase:= _
False, Orientation:=xlTopToBottom, DataOption1:=xlSortNormal, DataOption2 _
:=xlSortNormal
'---------------------------------------------------
'Autofilter:
mRng.AutoFilter Field:=1, Criteria1:=CuryID
mRng.AutoFilter Field:=2, Criteria1:="<=" & CDbl(mDate)
mRng.AutoFilter Field:=3, Criteria1:=BaseCuryID
'---------------------------------------------------
rngExcRate.Value = Sheet1.Range("A6:A" & MaxRow).SpecialCells(12).SpecialCells(xlCellTypeLastCell).Value
End Sub
[/highlight]
Sau khi Sort dử liệu rồi AutoFilter đúng điều kiện thì dòng ta cần lấy chính là dòng đầu sau khi AutoFilter
Nếu ta
Set Rng = ActiveSheet.AutoFilter.Range
thì
Rng.Offset(1).SpecialCells(12).Resize(1)
chính là dòng đầu tiên đấy
 
Upvote 0
Sau khi nghiên cứu kỹ bài này, tôi thấy chỉ cần 1 đoạn code ngắn thế này là đủ:
PHP:
Option Explicit
Sub GetExcRate1()
 Dim Temp As Variant
 With Range("A6").CurrentRegion
   Temp = .Cells.Value
   .Sort .Cells(2, 2), 2, , Header:=1
   .AutoFilter 1, [C2]: .AutoFilter 2, "<=" & CDbl([C1]): .AutoFilter 3, [C3]
   [C4] = .Offset(1, 3).SpecialCells(12).Areas(1).Resize(1, 1)
   .AutoFilter
   .Value = Temp
 End With
End Sub
Đoan:
Temp = .Cells.Value

.Value = Temp
Có thể bỏ qua nếu ta không có nhu cầu trả dử liệu về vị trí ban đầu
 

File đính kèm

Upvote 0
Code chạy tuyệt vời! Cảm ơn anh ndu96081631
Cái vụ SpecialCells(12).Areas(1).Resize(1, 1) em chưa hiểu lắm!
 
Upvote 0
Code chạy tuyệt vời! Cảm ơn anh ndu96081631
Cái vụ SpecialCells(12).Areas(1).Resize(1, 1) em chưa hiểu lắm!
Đương nhiên phải có Areas rồi ---> Vì sau khi ta Ctrl + G\Special\Visible Cell only thì vùng dử liệu được chọn sẽ là tất cả các cell đang "hiện" ---> Mà các cell này đôi lúc không nằm liền kề nhau (bị các dòng ẩn chia cắt) ---> Khi ấy nhưng vùng liền kề tạo thành 1 Area ---> Cả vùng Visible cell only này bao gồm nhiều Areas khác nhau
Nếu ta dùng
SpecialCells(12).Resize(1, 1)
Thì nó.. cóc chạy (không thể Resize các cell không liền kề )
Chỉ vậy thôi
Nói thêm:
Areas(1) là vùng thứ nhất
Areas(2) là vùng thứ hai

vân.. vân...
Và đương nhiên cell ta cần lấy nó đang nằm tại dòng thứ nhất của Areas(1)
Đơn giản thế thôi
 
Upvote 0
Nếu chỉ có lấy 1 giá trị 1 lần mà phải dùng Sub thì e rằng hơi đao to búa lớn.
Nếu như trong DATA mà có công thức thì khi trở lại ban đầu công thức sẽ thay thế bởi giá trị, công thức sẽ bị xóa đi, và tỉ giá trả về sẽ là #VALUE
Sort thì rất nhanh, tuy nhiên khi làm với mảng dữ liệu lớn, đang Sort mà cúp điện đột ngột thì DATA sẽ bị hỏng (tôi đã từng bị trường hợp như thế khi dùng desktop)

Vì vậy yêu cầu của các bài toán về DATAbase là không đụng chạm đến DATA để bảo đảm tính toàn vẹn của nó.
Nếu có cách nào không đụng chạm đến DATA được không nhỉ??

Thân!
 
Upvote 0
đụng chạm đến DATA được không nhỉ??

Thân!
Đương nhiên là được ---> Theo tôi, cách đơn giản nhất là thêm 1 cột STT
Ta chẳng thay đổi gì dử liệu cả, sau khi Sort xong, muốn quay về từ đầu thì sẽ dựa vào cột STT này mà "xơi"
Ẹc... Ẹc...
 
Upvote 0
Nếu chỉ có lấy 1 giá trị 1 lần mà phải dùng Sub thì e rằng hơi đao to búa lớn.
Nếu như trong DATA mà có công thức thì khi trở lại ban đầu công thức sẽ thay thế bởi giá trị, công thức sẽ bị xóa đi, và tỉ giá trả về sẽ là #VALUE
Sort thì rất nhanh, tuy nhiên khi làm với mảng dữ liệu lớn, đang Sort mà cúp điện đột ngột thì DATA sẽ bị hỏng (tôi đã từng bị trường hợp như thế khi dùng desktop)

Vì vậy yêu cầu của các bài toán về DATAbase là không đụng chạm đến DATA để bảo đảm tính toàn vẹn của nó.
Nếu có cách nào không đụng chạm đến DATA được không nhỉ??

Thân!
Giải pháp không sort dữ liệu thì em có nói rồi đó anh, dùng For...Next. Tuy nhiên nếu dữ liệu nhiều thì For..Next lâu lắm!
 
Upvote 0
Không For..next thì dùng obj.Find(..) vậy?
Mọi người nghĩ sao?
Thân.
 
Upvote 0
Sau khi nghiên cứu kỹ bài này, tôi thấy chỉ cần 1 đoạn code ngắn thế này là đủ:
PHP:
Option Explicit
Sub GetExcRate1()
 Dim Temp As Variant
 With Range("A6").CurrentRegion
   Temp = .Cells.Value
   .Sort .Cells(2, 2), 2, , Header:=1
  ...............
 End With
End Sub
Cho em hỏi tí, Tham số 2 trong cú pháp Sort có phải là Sort theo thứ tự từ lớn đến nhỏ không!?
 
Upvote 0
Cho em hỏi tí, Tham số 2 trong cú pháp Sort có phải là Sort theo thứ tự từ lớn đến nhỏ không!?

Đó chính là XlSortOrder trong cú pháp Sort Method (1 :Tăng : xlAscending; 2 :Giảm : xlDescending)

Range.Sort Method
Sorts a range of values.
Syntax
expression.Sort(Key1, Order1, Key2, Type, Order2, Key3, Order3, Header, OrderCustom, MatchCase, Orientation, SortMethod, DataOption1, DataOption2, DataOption3)|||
expression A variable that represents a Range object.
Parameters
Name|Required/Optional|Data Type|Description
Key1|Optional|Variant|Specifies the first sort field, either as a range name (String) or Range object; determines the values to be sorted.
Order1|Optional|XlSortOrder|Determines the sort order for the values specified in Key1.
Key2|Optional|Variant|Second sort field; cannot be used when sorting a pivot table.
Type|Optional|Variant|Specified which elements are to be sorted.
Order2|Optional|XlSortOrder|Determines the sort order for the values specified in Key2.
Key3|Optional|Variant|Third sort field; cannot be used when sorting a pivot table.
Order3|Optional|XlSortOrder|Determines the sort order for the values specified in Key3.
Header|Optional|XlYesNoGuess|Specifies whether the first row contains header information. xlNo is the default value; specify xlGuess if you want Excel to attempt to determine the header.
OrderCustom|Optional|Variant|Specifies a one-based integer offset into the list of custom sort orders.
MatchCase|Optional|Variant|Set to True to perform a case-sensitive sort, False to perform non-case sensitive sort; cannot be used with pivot tables.
Orientation|Optional|XlSortOrientation|Specifies if the sort should be in acending or decending order.
SortMethod|Optional|XlSortMethod|Specifies the sort method.
DataOption1|Optional|XlSortDataOption|Specifies how to sort text in the range specified in Key1; does not apply to pivot table sorting.
DataOption2|Optional|XlSortDataOption|Specifies how to sort text in the range specified in Key2; does not apply to pivot table sorting.
DataOption3|Optional|XlSortDataOption|Specifies how to sort text in the range specified in Key3; does not apply to pivot table sorting.
|||


For . . Next là vét cạn, chả lẽ không có cái khác nhanh hơn sao ??
Em thử Find chưa?? EM hay dùng Find lắm mà. Hay một cái nào đó khác chẳng hạn.
Miễn là làm sao đừng đụng đến DATA, khi em giải quyết chương trình của em cho khách hàng thì mới thấy sự toàn vẹn của DATA quan trọng như thế nào.

Thân!
 
Lần chỉnh sửa cuối:
Upvote 0
Cho em hỏi tí, Tham số 2 trong cú pháp Sort có phải là Sort theo thứ tự từ lớn đến nhỏ không!?
Chính xác!
Cái này tôi "phăng ra" khi record macro ---> Cũng dể nhận biết lắm! Này nhé:
- Khi bạn record macro mà có gọi 1 cửa sổ lệnh nào đó, nếu trong cửa số này có 2 Option Button cho ta chọn thì ăn chắc 9/10 cái trên sẽ là 1, cái dưới là 2
- Nếu cửa sổ lệnh có CheckBox thì TRUE tương đương với Check, FALSE tương đương với UnCheck
- Nếu cửa sổ lệnh có ComboBox thì giá trị mà ta chọn là số tương ứng với số dòng mà giá trị ấy chứa trong ComboBox (ví dụ: ComboBox chứa 3 giá trị chọn là Vàng, Xanh, Đỏ thì nếu ta viết ComboBox = 2 sẽ tương đương với chọn màu xanh)
vân vân và vân vân
Ví dụ:
Range(....).AdvancedFilter 1,.... thì số 1 tương ứng với việc ta chọn Filter the list, in-place --> Là Option Button nằm trên
Range(....).AdvancedFilter 2,.... thì số 2 tương ứng với việc ta chọn Copy to another location --> Là Option Button nằm dưới
Vậy thôi ---> Chỉ là xảo thuật
Thêm nữa: Mấy chứ xlYes, xlNo, gì gì đó khiến tôi rất khó nhớ ---> Tôi cứ suy nó ra số cho dể (muốn biết số = bao nhiêu thì gọi cửa sổ lệnh ra mà đếm ---> Dể ẹt)
 
Lần chỉnh sửa cuối:
Upvote 0
Còn cái vụ .SpecialCells (..) thì sao?
Trong cùng 1 khung mà có rất nhiều trường hợp.
Ví dụ như chọn .CurrentRegion thì lại không nằm trong SpecialCells.
Điều đó thật là khó hiểu?
Thân.
 
Upvote 0
Còn cái vụ .SpecialCells (..) thì sao?
Trong cùng 1 khung mà có rất nhiều trường hợp.
Ví dụ như chọn .CurrentRegion thì lại không nằm trong SpecialCells.
Điều đó thật là khó hiểu?
Thân.
Cái gì cũng có mức chính xác tương đôi thôi Po à! 1 vài tùy chọn không tuân theo quy luật như tôi nói ở trên ---> MsgBox chẳng hạn
(bởi vậy ở trên tôi nói: ĂN CHẮC 9/10 ---> Đâu dám 10/10)
Ẹc... Ẹc...
 
Lần chỉnh sửa cuối:
Upvote 0

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

Back
Top Bottom