Xin tư vấn code VBA

Liên hệ QC
Tôi tuân thủ nội quy khi đăng bài

tuan.chemi

Thành viên mới
Tham gia
4/1/13
Bài viết
39
Được thích
1
Sub tinh()
n = WorksheetFunction.CountA(Range("B:B"))
Dim c()
ReDim c(n + 1, n + 2)
For i = 2 To n + 1
For j = 2 To n + 2
c(i, j) = Cells(i, j)
Next j
Next i
For i = 2 To n + 1
s = c(i, i)
For j = 2 To n + 2
c(i, j) = c(i, j) / s
Next j
For j = 2 To n + 1
If j <> i Then
a = c(j, i)
For k = 2 To n + 2
c(j, k) = c(j, k) - a * c(i, k)
Next k
End If
Next j
Next i
For i = 2 To n + 1
Cells(i, n + 3) = " x" & i - 1
Cells(i, n + 4) = PhanSo(Val(c(i, n + 2)))
'Cells(i, n + 4) = c(i, n + 2)
Next i
End Sub


Đây là đoạn code giải hệ phương trình 3 ẩn. Vậy nếu muốn giải hệ 100 phương trình 100 ẩn thì viết lại thế nào ạ
 
Sub tinh()
n = WorksheetFunction.CountA(Range("B:B"))
Dim c()
ReDim c(n + 1, n + 2)
For i = 2 To n + 1
For j = 2 To n + 2

Đây là đoạn code giải hệ phương trình 3 ẩn. Vậy nếu muốn giải hệ 100 phương trình 100 ẩn thì viết lại thế nào ạ
Nếu theo kết cấu:
3 ẩn, dùng 2 "For Next",
thì suy ra:
100 ẩn, dùng 99 "For Next"
???
 
Upvote 0
Sub tinh()
n = WorksheetFunction.CountA(Range("B:B"))
Dim c()
ReDim c(n + 1, n + 2)
For i = 2 To n + 1
For j = 2 To n + 2
c(i, j) = Cells(i, j)
Next j
Next i
For i = 2 To n + 1
s = c(i, i)
For j = 2 To n + 2
c(i, j) = c(i, j) / s
Next j
For j = 2 To n + 1
If j <> i Then
a = c(j, i)
For k = 2 To n + 2
c(j, k) = c(j, k) - a * c(i, k)
Next k
End If
Next j
Next i
For i = 2 To n + 1
Cells(i, n + 3) = " x" & i - 1
Cells(i, n + 4) = PhanSo(Val(c(i, n + 2)))
'Cells(i, n + 4) = c(i, n + 2)
Next i
End Sub


Đây là đoạn code giải hệ phương trình 3 ẩn. Vậy nếu muốn giải hệ 100 phương trình 100 ẩn thì viết lại thế nào ạ
n = WorksheetFunction.CountA(Range("B:B")): Là gì vậy?
For i = 2 To n + 1: Số 2 là gì ? tại sao không là số 3

. . .
 
Upvote 0
@Chủ bài đăng: Tiêu đề của bạn đang là: "Xin tư vấn code VBA"
Tư vấn đầu tiên đến bạn là: Khi đăng Code ta nên bỏ vô thẻ [ PHP] . . . [/ Php] cho mọi người, trong đó có nhiều người nhã ý sẽ giúp bạn, đọc 1 cách trơn tru (tuột luốt), như:
Mã:
Sub Tinh()
n = WorksheetFunction.CountA(Range("B:B"))
Dim c():           ReDim c(n + 1, n + 2)
For i = 2 To n + 1
   For j = 2 To n + 2
      c(i, j) = Cells(i, j)
   Next j
Next i
For i = 2 To n + 1
   s = c(i, i)
   For j = 2 To n + 2
       c(i, j) = c(i, j) / s
   Next j
   For j = 2 To n + 1
      If j <> i Then
         a = c(j, i)
         For k = 2 To n + 2
            c(j, k) = c(j, k) - a * c(i, k)
         Next k
      End If
   Next j
Next i
For i = 2 To n + 1
   Cells(i, n + 3) = " x" & i - 1
   Cells(i, n + 4) = PhanSo(Val(c(i, n + 2)))
   'Cells(i, n + 4) = c(i, n + 2)    '
Next i
End Sub
 
Upvote 0
cho xin ví dụ về 1 bài toán 100 ẩn để thực hành code với ạ. hoặc nhiều bài khác có số ẩn khác nhau càng tốt
Sub tinh()
n = WorksheetFunction.CountA(Range("B:B"))
Dim c()
ReDim c(n + 1, n + 2)
For i = 2 To n + 1
For j = 2 To n + 2
c(i, j) = Cells(i, j)
Next j
Next i
For i = 2 To n + 1
s = c(i, i)
For j = 2 To n + 2
c(i, j) = c(i, j) / s
Next j
For j = 2 To n + 1
If j <> i Then
a = c(j, i)
For k = 2 To n + 2
c(j, k) = c(j, k) - a * c(i, k)
Next k
End If
Next j
Next i
For i = 2 To n + 1
Cells(i, n + 3) = " x" & i - 1
Cells(i, n + 4) = PhanSo(Val(c(i, n + 2)))
'Cells(i, n + 4) = c(i, n + 2)
Next i
End Sub


Đây là đoạn code giải hệ phương trình 3 ẩn. Vậy nếu muốn giải hệ 100 phương trình 100 ẩn thì viết lại thế nào ạ
 
Upvote 0
cho xin ví dụ về 1 bài toán 100 ẩn để thực hành code với ạ. hoặc nhiều bài khác có số ẩn khác nhau càng tốt
Sai diễn đàn rồi.
Cái bạn muốn là Toán Thuần Túy - Áp Dụng Toán Vi Tính
Đây là diễn đàn Excel. "A" trong VBA là "Application" hiểu theo ngữ cảnh là thực dụng.

Câu hỏi ngược lại cho bạn (và chủ thớt):
Khi nào trong Excel bạn có 100 ẩn để phải tìm?

Muốn thực hành code của Toán thuần túy thì tìm những diễn đàn chuyên Toán.

Tôi nói thế là vì các bạn KHÔNG CÓ CĂN BẢN VỀ LẬP TRÌNH THUẦN TÚY cho nên lẫn lộn Toán thực dụng với Toán thuần túy rồi.
Máy tính khác với lý thuyết là máy chỉ chứa được 15 chữ số cho nên bất cứ con toán nào cũng phải chấp nhận sai số. 3 lần nhân chia là 3 lần sai số, 100 lần nhân chia là 100 lần sai số. Con tính nhân chia thì sai số theo cấp số nhân chứ không phải cấp số cộng.

Tổng kết lại: giải hệ thống phương trình 100 ẩn số KHÔNG THỂ đem code của 3 ẩn số ra xài được. Bài toán nhân chia nhiều phải có những thuật toán để:
1. giảm thiểu sai số - đây là thuật toán khó nhất trong mọi thuật toán. Không biết cách giảm sai số, ma trận chéo góc hội tụ nhanh hơn chính thức.
2. giảm thiểu khả năng tràn số: một số khá nhỏ chia cho một số khá lớn sẽ có khả năng thành 0 - ngược lại số lớn chia cho số nhỏ thì bị tràn số.
3. tối ưu hóa: điển hình code trên khong có chỗ xét xem một lần cộng/trừ phương trình có thể nhiều hơn một dòng về hội tụ (n<>i -> a(i,j)= 0).
 
Lần chỉnh sửa cuối:
Upvote 0
n = WorksheetFunction.CountA(Range("B:B")): Là gì vậy?
For i = 2 To n + 1: Số 2 là gì ? tại sao không là số 3

. . .
Tôi nghĩ do cái Redim(n + 1, n + 2) mà ra cả. Lẽ ra phải Redim(1 to n, 1 to n + 1) thì mới đúng, để sau này mới có thể dùng For i = 1 to n được.
 
Upvote 0
Giải phương trình là một trong những căn bản của môn toán vi tính.
Bài toán giải hệ thống cũng là căn bản của giải phương trình.

Nhưng đây không phải là vấn đề của Excel.

Muốn học code VBA thì tìm bài Excel mà học. Bất cứ lý do gì khác cũng chỉ là ngụy biện.
Làm việc với số thực thì phải biết cách sử lý sai số. Ở GPE này những người rành sử lý toán số thực chỉ đếm trên đầu ngón tay.
 
Upvote 0
Tôi nghĩ do cái Redim(n + 1, n + 2) mà ra cả. Lẽ ra phải Redim(1 to n, 1 to n + 1) thì mới đúng, để sau này mới có thể dùng For i = 1 to n được.
c(i, j) = Cells(i, j)
Chủ thớt không có căn bản về VBA nên gán giá trị vào mảng bằng 2 vòng for theo từng cell, làm cho code khá rối và khai báo mảng phải lệ thuộc vào vị trí dữ liệu trên sheet

Cells(i, n + 4) = PhanSo(Val(c(i, n + 2)))
Thớt muốn tìm giải pháp xử lý nhưng không muốn công bố đầy đủ code gốc "PhanSo(Val(c(i, n + 2)))"
 
Upvote 0
Chủ thớt muốn giải phương trình 100 ẩn thì phải tìm hiểu giải thuật trước.
Có nhiều phương pháp, nhưng mình có thể mượn sự thuận tiện của bảng tính dùng phương pháp khử Gauss, nạp vào các hệ số của từng phương trình con: a1x + a2y + ... + a100kk = A; Xem giới hạn của các vị trí nạp hệ số như ma trận.
Sau đó ứng dụng các hàm nghịch đảo có trong Excel, dùng function có sẵn của Excel: (Hàm MINVERSE) để nghịch đảo ma trận; Hàm MMULT, hàm trả về ma trận tích của hai ma trận; Kết hợp vòng lặp từ đó tìm ra nghiệm của phương trình;

Tham khảo ví dụ: https://exceltable.com/en/analyses-reports/solving-equations-in-excel có cả file xls ví dụ đi kèm.
 
Lần chỉnh sửa cuối:
Upvote 0
Chủ thớt muốn giải phương trình 100 ẩn thì phải tìm hiểu giải thuật trước.
Có nhiều phương pháp, nhưng mình có thể mượn sự thuận tiện của bảng tính dùng phương pháp khử Gauss, nạp vào các hệ số của từng phương trình con: a1x + a2y + ... + a100kk = A; Xem giới hạn của các vị trí nạp hệ số như ma trận.
Sau đó ứng dụng các hàm nghịch đảo có trong Excel, dùng function có sẵn của Excel: (Hàm MINVERSE) để nghịch đảo ma trận; Hàm MMULT, hàm trả về ma trận tích của hai ma trận; Kết hợp vòng lặp từ đó tìm ra nghiệm của phương trình;

Tham khảo ví dụ: https://exceltable.com/en/analyses-reports/solving-equations-in-excel có cả file xls ví dụ đi kèm.
Nghe nói hàm MINVERSE Excel không chạy nổi 100*100
 
Upvote 0
tính ma trận nghịch đảo là 1 trong những thuật toán kinh điển nên tìm hiểu, bằng 1 cách thần kỳ nào đó nó tính hội tụ rất nhanh !
trong clip đính kèm có code bằng c , chạy theo phương pháp khử Gauss, chủ thớt có thể tự chỉnh lại theo vb ^^!
cách tính toán có thể tham khảo trong cuốn toán cao cấp !
...
Tính gì thì tính.
Toán cao cấp chỉ dẫn cho cách tính theo toán thuần túy.
Toán ứng dụng khác với toán thuần túy ở chỗ sai số do giới hạn mức chứa của kiểu double trên máy tính.
Nên nhớ rằng bất cứ kiểu số nào, máy tính chỉ chứa chính xác tới 15 chữ số. Với ma trận cỡ 10x10 giữ được sai số là mệt lắm rồi. 100x100 khả năng đáp án sai rất cao.
Những người nói chuyện 100x100 này, tôi e rằng lệnh so sánh If (a=b) Then còn chưa chắc đã viết đúng. Chớ nói chuyện lập trình toán ở đây.

Giải phương trình kiểu Gauss Elimination là đưa về ma trận nửa 0 (một góc của nó toàn 0's. Góc nào cũng được)

Chú thích:
Số Double không thể so sánh bằng nhau. Người biết làm việc với số thực luôn luôn đặt một sái số chấp nhận và dùng con toán If (abs(a-b) <= epsilon) Then a coi như bằng b với sai số epsilon.
 
Upvote 0
Web KT

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

Back
Top Bottom