Em cần giúp đỡ: Cách tính tổng các con số trong dãy số (1 người xem)

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

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

Plaza

Thành viên mới
Tham gia
14/10/10
Bài viết
42
Được thích
3
Em có 1 file số exel như sau:

Hình minh họa:
File.JPG

Cần tính tổng các con số ở cột A và cho kết quả tương xứng ở cột B
Như ví dụ đang tính dở ở cột B: B2 = 0+9+1+5+1+8+9+6+9+5 = 53)

Em cảm ơn nhiều !
 

File đính kèm

Dùng hàm tự tạo là khoẻ nhất

PHP:
Public Function tong(cell As Range) As Long
Dim i As Byte, kq As Long
For i = 1 To Len(cell)
  kq = kq + Val(Mid(cell, i, 1))
Next
tong = kq
End Function
 
Dùng hàm tự tạo là khoẻ nhất

PHP:
Public Function tong(cell As Range) As Long
Dim i As Byte, kq As Long
For i = 1 To Len(cell)
  kq = kq + Val(Mid(cell, i, 1))
Next
tong = kq
End Function

EM gửi kèm file trên đó, bác viết giúp em cái nhé. Khoản này em mù tịt! E cảm ơn nhiều !
 

File đính kèm

Có thể dùng công thức :
=MOD(INT(A2/10^0);10)+MOD(INT(A2/10^1);10)+MOD(INT(A2/10^2);10)+MOD(INT(A2/10^3);10)+MOD(INT(A2/10^4);10)+MOD(INT(A2/10^5);10)+MOD(INT(A2/10^6);10)+MOD(INT(A2/10^7);10)+MOD(INT(A2/10^8);10)+MOD(INT(A2/10^9);10)+MOD(INT(A2/10^10);10)
 
Dùng hàm tự tạo là khoẻ nhất

PHP:
Public Function tong(cell As Range) As Long
Dim i As Byte, kq As Long
For i = 1 To Len(cell)
  kq = kq + Val(Mid(cell, i, 1))
Next
tong = kq
End Function
Đố biết có cách nào không vòng lập mà vẫn tính được?
Ẹc... Ẹc...
 
Thank các bác nhiều ạ...tất cả đều rất hay !!!!!
 
Dùng công thức mảng này xem sao:
=SUM(--MID(A2, ROW(INDIRECT("1:" & LEN(A2))),1))
 
Đọc câu đố này "nhức đầu" à nghe!
Gợi ý: Hãy dùng CreateObject("VBScript.RegExp") để từng ký tự cách nhau bời 1 khoảng trắng. Xong, TRIM nó 1 phát rồi biến khoảng trắng này thành dấu "+". Cuối cùng Evaluate cái là ra kết quả
Ẹc... Ẹc...
 
Gợi ý: Hãy dùng CreateObject("VBScript.RegExp") để từng ký tự cách nhau bời 1 khoảng trắng. Xong, TRIM nó 1 phát rồi biến khoảng trắng này thành dấu "+". Cuối cùng Evaluate cái là ra kết quả
Ẹc... Ẹc...
Em cũng đã nghĩ đến cái này rồi, chỉ có cái này là không dùng vòng lập nhưng tối qua ngồi làm hoài mà không biết làm sao đưa cái khoảng trắng vô giữa các ký tự. Anh làm 1 cái cho em học đi.
 
Em cũng đã nghĩ đến cái này rồi, chỉ có cái này là không dùng vòng lập nhưng tối qua ngồi làm hoài mà không biết làm sao đưa cái khoảng trắng vô giữa các ký tự. Anh làm 1 cái cho em học đi.

Đại khái vầy nè:
Mã:
Function SumDigits(ByVal Num As String) As Long
  Dim tmp As String
  tmp = Val(Replace(Num, " ", ""))
  If Len(tmp) Then
    With CreateObject("VBScript.RegExp")
      .Global = True: [COLOR=#ff0000][B].Pattern = ""[/B][/COLOR]
      tmp = Trim(.Replace(tmp, " "))
    End With
    SumDigits = Evaluate(Replace(tmp, " ", "+"))
  End If
End Function
Chổ màu đỏ là chổ đánh dấu để ta thay thế đó
Từ đây ta có thể nghĩ đến bài toán khác: Tách từng ký tự của một chuổi và cho vào mảng, đúng không (bằng cách dùng thêm Split)
 
Đại khái vầy nè:
Mã:
Function SumDigits(ByVal Num As String) As Long
  Dim tmp As String
  tmp = Val(Replace(Num, " ", ""))
  If Len(tmp) Then
    With CreateObject("VBScript.RegExp")
      .Global = True: [COLOR=#ff0000][B].Pattern = ""[/B][/COLOR]
      tmp = Trim(.Replace(tmp, " "))
    End With
    SumDigits = Evaluate(Replace(tmp, " ", "+"))
  End If
End Function
Chổ màu đỏ là chổ đánh dấu để ta thay thế đó
Từ đây ta có thể nghĩ đến bài toán khác: Tách từng ký tự của một chuổi và cho vào mảng, đúng không (bằng cách dùng thêm Split)

Thấy anh làm 1 lần thế này rồi thì mới có thể làm theo được. Quá hay.
 
Gợi ý: Hãy dùng CreateObject("VBScript.RegExp") để từng ký tự cách nhau bời 1 khoảng trắng. Xong, TRIM nó 1 phát rồi biến khoảng trắng này thành dấu "+". Cuối cùng Evaluate cái là ra kết quả
Ẹc... Ẹc...


Đại khái vầy nè:
Mã:
Function SumDigits(ByVal Num As String) As Long
  Dim tmp As String
  tmp = Val(Replace(Num, " ", ""))
  If Len(tmp) Then
    With CreateObject("VBScript.RegExp")
      .Global = True: [COLOR=#ff0000][B].Pattern = ""[/B][/COLOR]
      tmp = Trim(.Replace(tmp, " "))
    End With
    SumDigits = Evaluate(Replace(tmp, " ", "+"))
  End If
End Function
Chổ màu đỏ là chổ đánh dấu để ta thay thế đó
Từ đây ta có thể nghĩ đến bài toán khác: Tách từng ký tự của một chuổi và cho vào mảng, đúng không (bằng cách dùng thêm Split)

Tôi nghĩ là hàm của bạn ndu:
1. Không hỗ trợ các chuỗi dài. vd. nếu ta có chuỗi "12345678987654321" thì nó có tận 17 chữ số nên sau câu lệnh tmp = Val(Replace(Num, " ", "")) ta sẽ có dạng tmp = "1,23456789876543E+16" (tổng cộng chỉ có 15 chữ số thôi). Vậy các thao tác tiếp theo sẽ sai hết.
2. Nếu chuỗi ngắn thì kết quả đúng với chuỗi có ít nhất 2 chữ số - vì vd. nếu chuỗi là "5" thì Evaluate("5") sẽ gây lỗi.
Nhưng code chưa hay lắm. Sao ta phải làm 2 bước Replace - 1 để chèn các dấu cách " ", sau đó lại thay dấu cách bằng dấu "+"? Chèn luôn dấu "+" thôi. Và không có dùng thêm hàm TRIM làm gì.
Mà dùng Pattern là "" không hay lắm. Dùng "\B\B" thì không bị chèn ở đầu và cuối.
Tôi mạn phép sửa code như sau:
Mã:
Function SumDigits(ByVal Num As String) As Long
Dim tmp As String, RegExp As Object
    Set RegExp = CreateObject("VBScript.RegExp")
    With RegExp
        .Global = True
        .pattern = "[^0-9]"
'       xóa tất cả các ký tự không là chữ số. Chỗ này thay cho hàm VAL để phục vụ chuỗi có > 15 chữ số 
        tmp = .Replace(Num, "")
        If Len(tmp) Then
'           dùng "\B\B" để không bị chèn ở đầu và cuối
            .pattern = [COLOR=#ff0000]"\B\B"
[/COLOR]            tmp = .Replace(tmp, "+")
            If Len(tmp) = 1 Then
                SumDigits = tmp
            Else
                SumDigits = Evaluate(tmp)
            End If
        End If
    End With
    Set RegExp = Nothing
End Function
 
Lần chỉnh sửa cuối:
Tôi nghĩ là hàm của bạn ndu:
1. Không hỗ trợ các chuỗi dài. vd. nếu ta có chuỗi "12345678987654321" thì nó có tận 17 chữ số nên sau câu lệnh tmp = Val(Replace(Num, " ", "")) ta sẽ có dạng tmp = "1,23456789876543E+16" (tổng cộng chỉ có 15 chữ số thôi). Vậy các thao tác tiếp theo sẽ sai hết.
2. Nếu chuỗi ngắn thì kết quả đúng với chuỗi có ít nhất 2 chữ số - vì vd. nếu chuỗi là "5" thì Evaluate("5") sẽ gây lỗi.
Nhưng code chưa hay lắm. Sao ta phải làm 2 bước Replace - 1 để chèn các dấu cách " ", sau đó lại thay dấu cách bằng dấu "+"? Chèn luôn dấu "+" thôi. Và không có dùng thêm hàm TRIM làm gì.
Mà dùng Pattern là "" không hay lắm. Dùng "\B\B" thì không bị chèn ở đầu và cuối.
Tôi mạn phép sửa code như sau:
Mã:
Function SumDigits(ByVal Num As String) As Long
Dim tmp As String, RegExp As Object
    Set RegExp = CreateObject("VBScript.RegExp")
    With RegExp
        .Global = True
        .pattern = "[^0-9]"
'       xóa tất cả các ký tự không là chữ số. Chỗ này thay cho hàm VAL để phục vụ chuỗi có > 15 chữ số 
        tmp = .Replace(Num, "")
        If Len(tmp) Then
'           dùng "\B\B" để không bị chèn ở đầu và cuối
            .pattern = [COLOR=#ff0000]"\B\B"
[/COLOR]            tmp = .Replace(tmp, "+")
            If Len(tmp) = 1 Then
                SumDigits = tmp
            Else
                SumDigits = Evaluate(tmp)
            End If
        End If
    End With
    Set RegExp = Nothing
End Function

Sao code này không chạy được nhỉ ?
 
Mã:
Function SumDigits(ByVal Num As String) As Long
Dim tmp As String, RegExp As Object
    Set RegExp = CreateObject("VBScript.RegExp")
    With RegExp
        .Global = True
        .pattern = "[^0-9]"
'       xóa tất cả các ký tự không là chữ số. Chỗ này thay cho hàm VAL để phục vụ chuỗi có > 15 chữ số 
        tmp = .Replace(Num, "")
        If Len(tmp) Then
'           dùng "\B\B" để không bị chèn ở đầu và cuối
            .pattern = [COLOR=#ff0000]"\B\B"
[/COLOR]            tmp = .Replace(tmp, "+")
            If Len(tmp) = 1 Then
                SumDigits = tmp
            Else
                SumDigits = Evaluate(tmp)
            End If
        End If
    End With
    Set RegExp = Nothing
End Function
[/QUOTE]
Tôitưởng code này tính được >15 số ?. >15 số thì chạy sai hết
 
Mã:
Function SumDigits(ByVal Num As String) As Long
Dim tmp As String, RegExp As Object
    Set RegExp = CreateObject("VBScript.RegExp")
    With RegExp
        .Global = True
        .pattern = "[^0-9]"
'       xóa tất cả các ký tự không là chữ số. Chỗ này thay cho hàm VAL để phục vụ chuỗi có > 15 chữ số 
        tmp = .Replace(Num, "")
        If Len(tmp) Then
'           dùng "\B\B" để không bị chèn ở đầu và cuối
            .pattern = [COLOR=#ff0000]"\B\B"
[/COLOR]            tmp = .Replace(tmp, "+")
            If Len(tmp) = 1 Then
                SumDigits = tmp
            Else
                SumDigits = Evaluate(tmp)
            End If
        End If
    End With
    Set RegExp = Nothing
End Function
Tôi tưởng code này tính được >15 số ?. >15 số thì chạy sai hết
Bạn thử sao mà nói SAI vậy?
 

File đính kèm

Lần chỉnh sửa cuối:
Chắc là nhẩm tính tổng các con số 1,23457E+14. Bỏ chữ E và dấu cộng (+) ra, tổng "trật lấc" đó mà.
Ẹc...

Cái này là anh đoán thôi nha, nhưng sao lại có số lớn quá vậy hén. Đọc không được luôn nè. Nếu 15 số đọc là 100 ngàn tỷ hả?
 
Lần chỉnh sửa cuối:
Cái này là anh đoán thôi nha, nhưng sao lại có số lớn quá vậy hén. Đọc không được luôn nè. Nếu 15 số đọc là 100 ngàn tỷ hả?
Đọc là tỷ tỷ thôi, là thật tôi cộng vẫn thấy sai ... bạn thử giúp đi
"123456789987654321". cho số này vào trong bảng thì =92
"-------------------------". cho vào cột để cộng thì = 90.
 
Đọc là tỷ tỷ thôi, là thật tôi cộng vẫn thấy sai ... bạn thử giúp đi
"123456789987654321". cho số này vào trong bảng thì =92
"-------------------------". cho vào cột để cộng thì = 90.

Mình tính thử thì ra 90, nếu ra 92 thì chắc là dư số nào ấy.
 
Lần chỉnh sửa cuối:
hic, công thức cùi bắp này (ở bài số 10):
=SUM(--MID(A2, ROW(INDIRECT("1:" & LEN(A2))),1))
cũng tính tổng các chữ số "123456789987654321" ra 90.
 
Mời thầy xem hộ em với, không biết là sai ở đâu,? thầy xem cái file thứ 2.


Khi mạn phép sửa code của bạn ndu tôi đã có nói rồi. Với chuỗi > 15 chữ số thì code sẽ không đúng nữa. Vd. nếu bạn nhập số 123456789987654321 thì Excel hiển thị cho bạn ở ô nhập là
1,23457E+17. Tuy nhiên Excel "lưu" trong bộ nhớ số chính xác hơn. Nếu bạn click vào ô thì trên thanh công thức bạn sé có là 123456789987654000 (tức không phải là
1,23457E+17 = 123457000000000000 mà chính xác hơn), tuy nhiên nó không phải số mà bạn đã nhập nữa.
Đấy mới chỉ là 1 vấn đề. Vấn đề thứ hai là khi số được truyền vào hàm SumDigits thì số có dạng
1,23456789987654E+17
Tất nhiên sau khi thực hiện lệnh tmp = .Replace(Num, "") thì
tmp = "12345678998765417"
Dĩ nhiên lúc này tổng các chữ số là 92.
Tôi đã nói rồi. Khi số có > 15 chữ số thì số truyền vào hàm sẽ có dạng x,y...zE+abc
Thậm chí nếu ta xét các th này bằng cách không thực hiện lệnh tmp = .Replace(Num, "") mà trước hết lược bỏ E thì số xy...z0...0 cũng không phải là số mà người dùng đã nhập vào ô trên sheet (số 123456789987654000 không phải là số đã nhập 123456789987654321)
Vậy không còn cách nào khác nữa. Nếu ta muốn hỗ trợ chuỗi dài tùy ý thì BẮT BUỘC ta phải nhập vào sheet dữ liệu ở dạng text. Hoặc ít ra thì với những số lớn phải nhập vào sheet dưới dạng text.
Bạn có 2 lựa chọn
a. Viết hàm hỗ trợ các số có tối đa 15 chữ số - và nhập vào sheet bình thường
b. Viết hàm hỗ trợ chuỗi dài bất kỳ - lúc này bắt buộc nhập vào sheet dưới dạng text. Chỉ riêng cái khoản số quá dài sẽ bị "làm tròn" đã đủ để nó khác với số người dùng đã nhập rồi. Vậy thì làm gì có chuyện tính tổng các chữ số mà người dùng nhập??? Chỉ có chuyện tính tổng các chữ số của số do "ông" Excel nhập thôi chứ. Tính tổng của ông Excel cũng dễ thôi nhưng yêu cầu là tính tổng của người dùng nhập cơ mà.
 
hic, công thức cùi bắp này (ở bài số 10):
=SUM(--MID(A2, ROW(INDIRECT("1:" & LEN(A2))),1))
cũng tính tổng các chữ số "123456789987654321" ra 90.

Tôi không rõ cái công thức mà bạn gọi là cùi bắp tính ra được bao nhiêu. Có điều chắc chắn là nếu ô A2 không được định dạng là TEXT thì sau khi gõ vào A2 chuỗi ký tự 123456789987654321 thì trong ô A2 chắc chắn không có cái đã gõ, tức 123456789987654321. Lúc đó thì công thức không thể trả về 90 được. Có mà ma thuật.
Thế nếu ô A2 được định dạng là TEXT và người dùng gõ 123456789987654321????
Thì lúc đó SumDigits sẽ trả về 90. Còn cùi bắp trả về bao nhiêu tôi không thử.
 
hehe có cách đấy thử vào hỏi bác goodle thần chưởng xem bác ý có biết không mấy anh

Thế tìm bác goodle ở đâu vậy??? Chả nhẽ một bác goodle cao thủ võ lâm tiếng tăm lừng lẫy trong thiên hạ mà tôi lại không nghe tới?
 
Thế nếu ô A2 được định dạng là TEXT và người dùng gõ 123456789987654321????
Thì lúc đó SumDigits sẽ trả về 90. Còn cùi bắp trả về bao nhiêu tôi không thử.

Sao bạn không test thử, nếu số trên định dạng là số thì công thức của bạn là bao nhiêu?Còn khi định dạng là kiểu text thì hàm của Hoangvuluan là OK
 
Sao bạn không test thử, nếu số trên định dạng là số thì công thức của bạn là bao nhiêu?Còn khi định dạng là kiểu text thì hàm của Hoangvuluan là OK

Bạn ạ, tôi không thử vì tôi nghĩ đơn giản là bạn hoangvuluan đã khẳng định như thế thì chắc chắn bạn ấy đã thử (với định dạng là text)
Bạn hỏi: nếu số trên định dạng là số thì công thức của bạn là bao nhiêu? Bạn ạ, bạn có đọc bài của tôi không? Tôi đã nói rõ là nếu tôi viết hàm phục vụ chuỗi dài tùy ý thì bắt buộc dữ liệu phải định dạng là text. Vậy câu hỏi của bạn là thừa bạn ạ. Muốn tranh luận thì phải đọc bài của người ta chứ, phải biết người ta đã nói gì, cái gì chưa nói chứ. Cái văn hóa tranh luận nó đòi hỏi như vậy bạn ạ.
 

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

Back
Top Bottom