Nhờ tìm, sửa lỗi Code trong bài của em

Liên hệ QC

Dauthivan

Thành viên tiêu biểu
Tham gia
15/8/08
Bài viết
565
Được thích
327
Sau khi đọc hôm nay em tự giải bài toán, tuy nhiên Code sai ở điểm gì chạy mãi không được (mặc dù em đã cố gắng so sánh với bài giải mẫu tương tự), xin nhờ mọi người chỉ giúp


Đề bài vẫn là bài cũ (em làm lại):
Baitoan1.jpg


Sau đó em viết Code:

PHP:
Sub Tinhtoan()
Dim sArr, Arr, i As Long, Congviec As Long, Nhom As Long, DongDau As Long, DongCuoi As Long
DongDau = 4
DongCuoi = [C650000].End(xlUp).Row
sArr = Range("A" & (DongDau) & ":C" & (DongCuoi)).Value
Range("G" & (DongDau) & ":G" & (DongCuoi)).ClearContents
Arr = Range("G" & (DongDau) & ":G" & (DongCuoi)).Value
For i = 1 To DongCuoi
If sArr(i, 1) <> "" Then
Congviec = i
ElseIf sArr(i, 1) = "" & sArr(i, 2) = "" Then
Nhom = i
Arr(Nhom, 1) = "=sum(R[1]C:R[" & (i - Nhom) & "]C)*RC[-2]"
Arr(Congviec, 1) = "=sum(R[" & (Nhom - Congviec) & "]C"
Else:
Arr(i, 1) = "=RC[-1]*RC[2])"
End If
Next
Range("G" & (DongDau) & ":G" & (DongCuoi)).Value = Arr

End Sub
 

File đính kèm

Tôi khuyên bạn nên tập làm từ những bài đơn giản và tự bạn làm từ đầu tới cuối. Có như vậy thì mới tiến bộ nhanh được.
Như code này của bạn, vì bạn làm theo một cách máy móc trong khi bạn chưa hiểu rõ thuật toán nên còn nhiều chỗ sai lắm. Mà thuật toán thì rất quan trọng trong lập trình, bạn phải rèn luyện bằng cách tự suy nghĩ chứ bạn lấy code của người khác sửa lại thì sẽ không bao giờ tiến bộ được đâu. Có thể lúc đầu thuật toán của bạn không hay nhưng đó không phải là điều quan trọng, ai cũng trải qua giai đoạn đó thôi.
Tôi bỏ qua phần thuật toán, chỉ nói phần cấu trúc lệnh thì code của bạn sai những chỗ này:
1. File của bạn là Excel 2003, chỉ có 65536 dòng nhưng bạn sử dụng ô C650000
2. Ví dụ biến DongDau có giá trị là 4, biến DongCuoi có giá trị là 183 thì mảng của bạn chỉ có 180 dòng (= 183 - 4 + 1) nhưng bạn lại gọi đến dòng 183 (For i = 1 to DongCuoi)
3. Tại dòng ElseIf, bạn dùng toán tử &. Đúng ra thì chỉ được dùng And hoặc Or.
 
Upvote 0
*Các lỗi:

Ngoài các lỗi anh Huuthang_bd đã chỉ ra, file mắc tương đối nhiều lỗi, cụ thể:
- Phân biệt sArr(i, 1) khác hẳn với Cells(i,1) bạn nhé.

- Công thức:
Arr(Congviec, 1) = "=sum(R[" & (Nhom - Congviec) & "]C": chữ Sum ở đây không có ý nghĩa gì cả bởi nó chỉ là 1 ô (không phải là tập hợp các ô từ ô...đến ô),

Cụ thể, nếu công việc đầu tiên ban đầu đi đến dòng VL thì nó bằng VL, khi đến dòng NC thì nó bằng NC (quên không cộng dồn VL), đến dòng MTC nó lấy luôn cái này (quên 2 th
ằng kia VL, NC)

Công thức đúng:
PHP:
Arr(CongViec, 1) = Arr(CongViec, 1) & "+R[" & (Nhom - CongViec) & "]C"

(Trước đó không quên dòng Arr(CongViec, 1) = "=" ở trên nhé)
---------------------
Việc đặt đồng thời khi xử lý hàm If thế này:
PHP:
Nhom = i
Arr(Nhom, 1) = "=sum(R[1]C:R[" & (i - Nhom) & "]C)*RC[-2]"

là sai bởi sẽ xảy ra trường hợp i=Nhom thì i-Nhom = 0 (dẫn đến tình trạng vòng lặp vô hạn ví dụ G5=sum(G5+G6)

>> khi vi
ết thuật toán việc đặt thứ tự tính toán rất quan trọng, không phải thích để ở trên hay dưới tuỳ ý được.
---------------------------
Công thức: Arr(i, 1) = "=RC[-1]*RC[2])" đánh thừa phải sửa là Arr(i, 1) = "=RC[-1]*RC[2]" (Nếu đánh thừa khi đến dòng chi tiết không thực hiện nhân được >> lỗi, Code không tiếp tục chạy xuống nữa (nghỉ cho khoẻ).
------------------------------



Code đúng:

PHP:
Sub Congthuc()
Dim sArr, Arr, i As Long, CongViec As Long, Nhom As Long, DongDau As Long, DongCuoi As Long
DongDau = 4
DongCuoi = [C65536].End(xlUp).Row
sArr = Range("A" & (DongDau) & ":C" & (DongCuoi)).Value
Range("G" & (DongDau) & ":G" & (DongCuoi)).ClearContents
Arr = Range("G" & (DongDau) & ":G" & (DongCuoi)).Value
For i = 1 To UBound(sArr, 1)
If sArr(i, 1) <> "" Then
CongViec = i
Arr(CongViec, 1) = "="
ElseIf sArr(i, 1) = "" And sArr(i, 2) = "" Then
Nhom = i
Arr(CongViec, 1) = Arr(CongViec, 1) & "+R[" & (Nhom - CongViec) & "]C"
Else:
Arr(Nhom, 1) = "=sum(R[1]C:R[" & (i - Nhom) & "]C)*RC[-2]"
Arr(i, 1) = "=RC[-2]*RC[-1]"
End If
Next
Range("G" & (DongDau) & ":G" & (DongCuoi)) = Arr
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Các bạn trên đã nặng nhẹ với bạn rồi, mình chỉ xin thêm vài í, như sau

(1) Bạn cần tận dụng mọi hỗ trợ từ VBE, như việc thụt đầu dòng các dòng lệnh cho ngay hàng, ngay cột
VD:

PHP:
 Sub TapTành()
  Dim GPE As String, Arr(), jJ
  
  For Jj =1 To EndRow
      If IsNumeric(Cell(jJ+3,1).Value) then
          Arr(jJ,1)= Jj+2
      Else
          GPE= "Nothing"
      End If
  Next Jj
End Sub

(2) Luôn trao đổi thông tin với đứa con tinh thần của mình để biết được tâm tư tình cảm của nó;
Bằng gì ư, bằng lệnh MsgBox Jj, , GPE chẳng hạn!

(3) Sự học là đi từ dễ đến khó, từ cụ thể đến trừu tượng; Mà vấn đền mình muốn nhắc bạn là mảng là 1 cái hơi trừu tượgn với tôi & bạn.
Nếu là tôi, khi nhận nhiệm vụ này, tôi ngồi lật qua lật lại trang tính để tìm cách đi đến đích thích hợp với khả năng nhất;
& cách để đạt mục đích trước tiên mà tôi nhìn thấy là:

CSDL (cơ sở dữ liệu) khảo sát tạo ra từng cụm công việc; trong đó mỗi cụm có thể có tối đa là 3 công việc nhỏ gộp lại & công việc nữa là tổng của nhiều nhất là 3 công việc đó gộp lại;

Dừng ở đây để nói thêm về CSDL của bạn:
Bạn giả lập CSDL quả là nhiều, nhưng không cần thiết nhiều như vậy;
Í mình là chỉ cần khoảng hơn mươi công việc, nhưng tổ hợp được tất thẩy các fương án có thể về Máy/Nhân công/Vật liệu;
Để làm chi vậy: Để kiểm tra tính đúng đắn của macro chứ không ngoài mục đích nào khác.
Còn như của bạn, muốn kiểm tính đúng của macro, ta fải chạy xuống tới dòng 80 (công việc 16) mới thấy hết vấn đề, Như vậy là từ dòng 4 đến dóng 80 rất nhiều công việc không đán có trong CSDL giả lập của bạn.

(4) Bàn thêm với bạn về thuật toán: Đơn giản nhất, theo tôi thuật toán sẽ là
Tìm ra các ô đã đánh dấu các công việc trong cột 'A' - Bằng fương thức SpecialCell; (VD đó là ô Cls)
Gán vùng này gồm Cls & các ô rỗng bên dưới nó & mở rọng về bên fải (cột) hết cỡ thơ mộc vô biến nào đó
& ta chỉ khảo sát các thành fần của vùng này theo đủ các tiêu chỉ mà nó đáng có.
Thêm nữa, xin nhắc bạn tận dụng ưu điểm của 3 tiêu chí này có 3 chữ cái đầu khác nhau (V, N, M) để ta định vị ra chúng

Ta làm với từng khối vùng như vậy lần lượt cho đến hết.

(*) Chỉ sau khi cái đơn giản ta đã đạt đúng kết quả rồi, thì ta mới tìm cách cải tiến về tốc độ chương trình hay gì gì khác.
Việc học VBA không thể đối cháy giai đoạn được; Chớ nóng vội, vì GPE.COM sẽ còn bên bạn dài dài để hỗ trợ bạn & tôi cơ mà!

/-(ãy xem đây là những lời khuyên của 1 người tự học VBA như bạn!

(húc thành công & Xuân vui vẻ!
 
Upvote 0
/-(ãy xem đây là những lời khuyên của 1 người tự học VBA như bạn!

(húc thành công & Xuân vui vẻ!

Cảm ơn bác, lời khuyên của bác thật sự rất bổ ích cho những người mới tự học VBA như em. Quả thực, khi bước đầu bước vào bài đầu tiên này do chưa có một chút kiến thức cũng như kinh nghiệm nào về VBA, thành thử ra viết Code mà đôi khi còn lúng túng cú pháp đó có đúng hay không?

Chính vì vậy, điều em mong mỏi là đi tìm sự trợ giúp của VBE, sự chia sẻ kinh nghiệm của mọi người đi trước, để sau này những kiến thức đó có thể giúp em thực sự kiểm soát được kết quả của từng dòng mình viết.

Vâng, vì là bài toán giả định thôi, em biết sẽ có công việc không có thành phần cấu tạo nên các dòng VL,NC,MTC hoàn toàn trống không có công thức khi chạy. Nhưng điều đó bây giờ chưa cần thiết lắm (biết hạn chế của nó là đã là tốt rồi), điều quan trọng là em may mắn có thêm rất nhiều kiến thức sau mỗi lần được mọi người, các anh chị, các thày trên diễn đàn chỉ giúp.

Thực sự em không biết nói gì để cảm ơn tấm lòng của mọi người đã nhiệt tình giúp đỡ em. Em xin chúc tất cả mọi người chuẩn bị đón Tết, bước sang năm mới đạt được nhiều thành công, hạnh phúc.
 
Chỉnh sửa lần cuối bởi điều hành viên:
Upvote 0
Web KT

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

Back
Top Bottom