Function TongCT(Rng As Range, Optional CT = "Mi") As Double
Dim i As Long, Temp As Double
For i = 1 To Rng.Rows.Count
With Rng.Resize(1).Offset(i - 1)
Select Case CT
Case "Mi": Temp = WorksheetFunction.Min(.Cells)
Case "Ma": Temp = WorksheetFunction.Max(.Cells)
End Select
TongCT = TongCT + Temp
End With
Next i
End Function
Không biết em hiểu vấn đề có đúng ý anh không?
(code chắc cũng chưa được tối ưu lắm)
Function SumMax(Data)
Set ArrData = Data
For i = 1 To ArrData.Rows.Count
For j = 1 To ArrData.Columns.Count
Maxi = IIf(IsNumeric(ArrData(i, j)) And ArrData(i, j) >= Maxi, ArrData(i, j), Maxi)
Next j
SumMax = SumMax + Maxi
Maxi = 0
Next i
End Function
Xin PTM0412 chuyển hàm của bạn thành hàm tổng hợp, như sau:
PHP:
Function TgCucTri(ByVal InRange As Range, Optional CucTieu As Boolean = True) As Double
Dim ArrRange As Range: Dim CucTri As Double
Dim Ff As Long, Jj As Long
Set ArrRange = InRange
For Ff = 1 To ArrRange.Rows.Count '
CucTri = Val(ArrRange(Ff, 1))
For Jj = 1 To ArrRange.Columns.Count
If Val(ArrRange(Ff, Jj)) > CucTri Xor CucTieu Then CucTri = ArrRange(Ff, Jj)
Next Jj
TgCucTri = TgCucTri + CucTri
Next Ff
End Function
- And : Cùng phải thỏa mãn (Các phần tử đều là True) -> TRUE
- Or : Chỉ cần 1 phần tử thỏa mãn (Có ít nhất 1 phần tử là True) -> TRUE
- XOr : Các phần tử không giống nhau (Có cả True, False) --> TRUE
Function SumMaxMin(Rng As Range, Optional Cond As Byte = 1) As Double
For i = 1 To Rng.Rows.Count
With WorksheetFunction
SumMaxMin = SumMaxMin + Choose(Cond, .Max(Rng.Rows(i)), .Min(Rng.Rows(i)))
End With
Next i
End Function
- And : Cùng phải thỏa mãn (Các phần tử đều là True) -> TRUE
- Or : Chỉ cần 1 phần tử thỏa mãn (Có ít nhất 1 phần tử là True) -> TRUE
- XOr : Các phần tử không giống nhau (Có cả True, False) --> TRUE
Ta xét hàm sau (được viết lại từ 'Help' về toán tử này trong VBA, chắc rõ hơn ít nhiều
PHP:
Function MyCheck(Cas As Byte) As Boolean
Dim A, B, C, D
A = 10: B = 8: C = 6: D = Null ' Initialize variables.'
Select Case Cas
Case 1
MyCheck = A > B Xor B > C ' True;True => False.'
Case 2
MyCheck = B > A Xor B > C ' False;True => True.'
Case 3
MyCheck = B > A Xor C > B ' False;False => False.'
Case 4
MyCheck = B > D Xor A > B ' Returns Null.'
Case 5
MyCheck = A Xor B ' Returns 2 (bitwise comparison).'
Case 6
MyCheck = A Xor D ' Returns NULL.?'
End Select
End Function
Cái XOR này trong ngành điện tự động hóa em xài hoài ---> Ứng dụng của nó thì vô vàn... Ví dụ đơn cử là mạch flip-flop (ví dụ cụ thể về ứng dụng: mở cửa--> đèn sáng --> đóng cửa ---> đền vẫn sáng ---> mở cửa tiếp ---> đèn tắt ---> đóng cửa lại ---> đèn tắt...)
Không ngờ trong Excel cũng chơi món này
Biểu diển nó trong công thức Excel sẽ là: =OR(AND(A1,NOT(B1)),AND(NOT(A1),B1))
(Với A1, B1 là các giá trị logic)
Thú thật mình cũng chỉ mới lõm bõm về nó ở trang WEB Ozgrid.com mà thôi
Ví dụ hàm xếp trật tự các ký tự trong 1 chuỗi, như sau:
PHP:
Function StrSort(ByVal StrC As String, Optional bDescending As Boolean = False) As String
' sorts a blank-delimited string.'
Dim Matric() As String, GPE As String ' temp string for exchange.'
Dim Ww As Long, Zz As Long, Jj As Long
Matric = Split(StrC, " "): Ww = UBound(Matric)
For Zz = 0 To Ww
Matric(Zz) = Trim(Matric(Zz))
Next
If Ww <= 1 Then
StrSort = StrC
Else
For Zz = 0 To Ww - 1
For Jj = Zz + 1 To Ww
If (Matric(Jj) < Matric(Zz)) Xor bDescending Then
GPE = Matric(Zz): Matric(Zz) = Matric(Jj)
Matric(Jj) = GPE
End If
Next Jj
Next Zz
StrSort = Join(Matric, ", ")
End If
End Function
Xin đề nghị các bạn thử tìm cách khác mà không sử dụng toán tử khó hiểu này được hay không?
Xin cảm ơn trước nhiều lắm đó nha!!
Thú thật mình cũng chỉ mới lõm bõm về nó ở trang WEB Ozgrid.com mà thôi
Ví dụ hàm xếp trật tự các ký tự trong 1 chuỗi, như sau:
PHP:
Function StrSort(ByVal StrC As String, Optional bDescending As Boolean = False) As String
' sorts a blank-delimited string.'
Dim Matric() As String, GPE As String ' temp string for exchange.'
Dim Ww As Long, Zz As Long, Jj As Long
Matric = Split(StrC, " "): Ww = UBound(Matric)
For Zz = 0 To Ww
Matric(Zz) = Trim(Matric(Zz))
Next
If Ww <= 1 Then
StrSort = StrC
Else
For Zz = 0 To Ww - 1
For Jj = Zz + 1 To Ww
If (Matric(Jj) < Matric(Zz)) Xor bDescending Then
GPE = Matric(Zz): Matric(Zz) = Matric(Jj)
Matric(Jj) = GPE
End If
Next Jj
Next Zz
StrSort = Join(Matric, ", ")
End If
End Function
Xin đề nghị các bạn thử tìm cách khác mà không sử dụng toán tử khó hiểu này được hay không?
Xin cảm ơn trước nhiều lắm đó nha!!
Không chỉ VBA trong excel đâu NDU à, mà mình cũng thấy nó trong Pascal, VB gì đó V.V. . .
Hình như là toàn bộ đó!
Trong code sắp xếp trên, người ta dùng toán tử xOR để xây dựng điều kiện:
Mã:
If (Matric(Jj) < Matric(Zz)) Xor bDescending Then
điều này tương đương với việc tách điều kiện của biến bDescending:
Nếu không dùng xOR, thì phải dùng 2 câu IF:
PHP:
If bDescending Then ' sắp giảm '
If Matric(Jj) < Matric(Zz) then
...
End If
Else
If ...
...
End If
End If
Toán tử xOR còn được gọi là toán tử "mặt nạ" vì nó cho phép tạo các phép "che" bit. Ví dụ, áp dụng vào việc chuyển đổi chữ hoa sang chữ thường:
Ta biết chữ A mã ASCII là 65, a: 97, space (blank) là 32 (kí hiệu sp)
giá trị 32 biểu diễn trong hệ nhị phân 8 bit:
00100000 (= 2^5 = 32)
ký tự a được biểu diễn là: 01100001 ( = 64 + 32 + 1) = 2^6 + 2^5 + 2^0
ký tự A được biểu diễn là: 01000001 ( = 64 + 1)
các ký tự hoa-thường trong bảng mã ASCII sai khác nhau chỉ 1 bit số 5 (đếm từ phải sang trái, từ 0 đến 7, bit cao nhât là 7)
do đó phép toán: a xOR sp -> sẽ tắt bit số 5 của a tạo ra kết quả là 65 = A (a hoa)
tương tự A xOR sp -> bật bit số 5 -> 97 = a (a thường)
Trở lại code trên: điều kiện: (x < y) xOR z (với z = -1 hoặc 0 là 2 giá trị boolean True và False trong VBA) (lưu ý z=-1 biểu diễn 8 bit là 10000000 (bit 7 bằng 1)
Nếu chỉ quan tâm đến khía cạnh logic thì điều kiện trên sẽ có các trường hợp sau:
False xOR False -> False
False xOR True -> True ===> sắp giảm thì xét điề kiện khi x<y sai
True xOR False -> True ====> sắp tăng thì xét điều kiện khi x<y đúng
True xOR True -> False
Xin giới thiệu hàm tìm cực trị của thang đo trên đồ thị, chúng ta cùng ngâm cứu
PHP:
Function CucTri(rData As Range) As Variant
'Returns a two-element variant containing a min and max value for chart'
'scales based on the min and max values in the data range, computing'
'values with the least number of significant digits necessary for the'
'data range to cover some minimum fraction (dMinFrac) of the chart range.'
Const dMinFrac As Double = 0.8
Dim NumMin As Double, NumMax As Double 'min and max of data range'
Dim GHD As Double, GHT As Double ' min and max of chart range'
Dim dLog As Double: Dim nDigit As Integer
With WorksheetFunction
'Get the min and max of the data range'
NumMin = .Min(rData): NumMax = .Max(rData)
'If the data has a zero-span range, return that range'
If NumMin = NumMax Then
CucTri = Array(NumMin, NumMax)
Exit Function '- - - - - - - - - - - - - - - - - - - - - - - - ->'
End If
'Compute the digit position for one significant digit'
dLog = Log(.Max(Abs(NumMax), Abs(NumMin))) / Log(10)
nDigit = CInt(dRndUpDn(-dLog, 1, False))
Do
'Round the min down, and the max up, to the computed significance'
GHD = dRndUpDn(NumMin, nDigit, False)
GHT = dRndUpDn(NumMax, nDigit, True)
'If this chart range is sufficiently narrow for data range, finish;'
'otherwise, add another significant digit and try again'
If (NumMax - NumMin) / (GHT - GHD) >= dMinFrac Then
Exit Do '- - - - - - - - - - - - - - - - - - - - - - - - ->'
Else
nDigit = nDigit + 1
End If
Loop
End With
'Return the computed values as a two-element variant
CucTri = Array(GHD, GHT)
End Function
PHP:
Function dRndUpDn(dNum As Double, nDigit As Integer, bUpdn As Boolean) As Double
'Returns a Double rounded up or down to the specified significance.'
'Unlike ROUNDDOWN() and ROUNDUP(), this function rounds in absolute'
'direction, rather than toward or away from zero.'
'bUpDn = False => Round Down'
'= True => Round Up'
If dNum = 0 Then Exit Function '- - - - - - - - - - - - - - - - - ->'
With WorksheetFunction
If dNum > 0 Xor bUpdn Then
dRndUpDn = .RoundDown(dNum, nDigit)
Else
dRndUpDn = .RoundUp(dNum, nDigit)
End If
End With
End Function
|
A
|
B
|
C
|
D
|
||. . .|||
5|50|1250|||
6|41|
2487
|||
7|
11
|
110
|
10
|
60|
8|
60
|596|
100
|
2500
|
9|26|125|||
10|18|587|||
|||||
Ta chọn 2 ô C77 ta nhập cú pháp =CucTri(A5:A10) & kết thúc bằng tổ hợp 3 phím cho hàm mảng
Tại C88 ta lại nhập cú pháp hàm =CucTri(B5:B10) & cũng kết thúc như trên; Ta sẽ nhận được kết quả như trong
Vầy mới tổng quát hơn chứ: =SUMPRODUCT(SUBTOTAL(4, OFFSET($A$1:$C$10,ROW(INDIRECT("1:"&ROWS($A$1:$C$10)))-1,,1,))) Nên đặt name cho vùng dử liệu: =SUMPRODUCT(SUBTOTAL(4, OFFSET(Vung,ROW(INDIRECT("1:"&ROWS(Vung)))-1,,1,)))
Với Vung =$A$1:$C$10
hãy thử mấy mấy số có số lớn hơn số dòng của excel thì thấy ngay thôi mà.
Vì hàm row chỉ làm việc đúng với số >0 và không vượt quá số dòng tối đa của excel.
hãy thử mấy mấy số có số lớn hơn số dòng của excel thì thấy ngay thôi mà.
Vì hàm row chỉ làm việc đúng với số >0 và không vượt quá số dòng tối đa của excel.
-- CV--
Trong vùng A1:C10, em gõ vào một ô bất kỳ một con số là 1 tỷ, em có thấy sai gì đâu anh! Tiếp theo em gõ tiếp con số (-2 tỷ), cũng chẳng thấy sai gì cả!