В настоящее время я пытаюсь реализовать Clark & Wright Savings Heurisitc в VBA, но в настоящее время я столкнулся с некоторыми проблемами. Я довольно новичок в VBA, и эта ошибка (91) хранится в подобных ситуациях, что заставило меня поверить, что мне не хватает некоторых важных знаний. Далее я представляю вам код:Ошибка 91 в VBA с использованием классов
Public Sub CWsavings()
Dim i As Integer
Dim j As Integer
Dim k As Integer
Dim aux As Integer
Dim d As Integer
Dim r As Integer
Dim Cu(200) As customer
Dim De(12) As Depot
For i = 1 To 200
Set Cu(i) = New customer
Cu(i).custID = i
Cu(i).longitude = ThisWorkbook.Sheets("Folha1").Cells(i + 1, 2)
Cu(i).latitude = ThisWorkbook.Sheets("Folha1").Cells(i + 1, 3)
Cu(i).lt = ThisWorkbook.Sheets("Folha1").Cells(i + 1, 4)
Cu(i).et = ThisWorkbook.Sheets("Folha1").Cells(i + 1, 5)
Cu(i).weekdemand = ThisWorkbook.Sheets("Folha1").Cells(i + 1, 6)
Cu(i).peakdemand = ThisWorkbook.Sheets("Folha1").Cells(i + 1, 7)
Cu(i).D1 = ThisWorkbook.Sheets("Folha1").Cells(i + 1, 8)
Cu(i).D2 = ThisWorkbook.Sheets("Folha1").Cells(i + 1, 9)
Next i
For j = 1 To 12
Set De(j) = New Depot
De(j).depotID = j
De(j).Dname = ThisWorkbook.Sheets("Folha1").Cells(i + 1, 13)
De(j).latitude = ThisWorkbook.Sheets("Folha1").Cells(i + 1, 14)
De(j).longitude = ThisWorkbook.Sheets("Folha1").Cells(i + 1, 15)
De(j).ncust = ThisWorkbook.Sheets("Results").Cells(j, 7)
De(j).nroute = 0
For k = 1 To De(j).ncust
aux = ThisWorkbook.Sheets("Results").Cells(j + 1, 10 + k)
Call De(j).SetCustomer(Cu(aux), k)
Next k
Next j
For d = 1 To 12
Dim M(30, 30) As Double
Dim maxsav As Double
Dim maxpos(2) As Integer
Dim connorder(676, 2) 'order of connections for routing
Dim it As Integer
it = 0
For i = 1 To De(d).ncust
For j = 1 To De(d).ncust
M(i, j) = CalcSavings(De(d), De(d).customer(i), De(d).customer(j)) ' error here
Next j
Next i
itbegin:
maxsav = 0
maxpos(1) = 0
maxpos(2) = 0
For i = 1 To De(d).ncust
For j = 1 To De(d).ncust
If i <> j Then
If M(i, j) > maxsav Then
maxsav = M(i, j)
maxpos(1) = i
maxpos(j) = j
End If
End If
Next j
Next i
it = it + 1
connorder(it, 1) = maxpos(1)
connorder(it, 2) = maxpos(2)
If it < De(d).ncust * De(d).ncust - ncust Then
M(maxpos(1), maxpos(2)) = 0
GoTo itbegin
End If
Next d
End Sub
Public Function CalcSavings(d As Depot, C1 As customer, C2 As customer)
Dim id As Double
Dim dj As Double
Dim ij As Double
id = DeptDist(C1, d)
dj = DeptDist(C2, d)
ij = CustDist(C1, C2)
CalcSavings = id + dj - ij
End Function
Класс Depot:
Public depotID As Integer
Public Dname As String
Public latitude As Double
Public longitude As Double
Private customers(200) As customer
Public ncust As Integer
Private routes(500) As route
Public nroute As Integer
Public Sub addcust(C As customer)
ncust = ncust + 1
Set customers(ncust) = C
End Sub
Public Sub addroute(R As route)
nroute = Me.nroute + 1
Set routes(Me.nroute) = R
End Sub
Public Property Get customer(i As Integer) As customer
customer = customers(i)
End Property
Public Sub SetCustomer(C As customer, i As Integer)
Set customers(i) = C
End Sub
Public Property Get route(i As Integer) As route
route = routes(i)
End Property
Public Sub SetRoute(R As route, i As Integer)
Set routes(i) = R
End Sub
(класс депо Обновлено)
А класс Customer:
Public custID As Integer
Public latitude As Double
Public longitude As Double
Public lt As Double
Public et As Double
Public weekdemand As Integer
Public peakdemand As Integer
Public D1 As Integer
Public D2 As Integer
Я сожалею для длинного поста любая помощь будет оценена по достоинству.
Любые указатели на линии, с которой происходит ошибка? Одна вещь, которая бросается в глаза, глядя на ваш код, заключается в том, что вы начинаете индексы массивов в 1, тогда как по умолчанию они начинаются с 0 в Excel. При объявлении массива число внутри круглых скобок не является размером, это максимальный индекс. Например, 'Dim cu (200), поскольку клиент' объявит массив с индексами, идущими от 0-200 (размер = 201) –
Обычно ошибка 91 связана с не настроенными объектами, но ваш код выглядит нормально. Единственное, что я вижу, что может вызвать проблему, - это индексы массивов (поскольку ваши массивы имеют дело с объектами). –
@ BernardSaucier, я знаю, что в vba массивы начинаются с нуля, я программировал это в виду. Но если я закодирую петли, чтобы идти от 1 до 200 (что означает игнорирование 0), не должно быть никаких проблем правильно? Что может быть проблемой при работе с массивами объектов, «вызвать неверный индекс» и, следовательно, объект не существует? – user3187129