Я новичок на форуме и в Excel/VBA. Я прохожу курс прикладного/продвинутого финансового анализа, и наша задача на этой неделе — отобразить график амортизации в окне сообщений, используя 3 (или 4) поля ввода. Итак, полная прозрачность: это школьная работа, но я клянусь всем святым, что потратил мучительное количество времени на это задание, и я застрял. Да, я обратился к своему профессору, но, к сожалению, у меня недостаточно знаний, чтобы следовать ее указаниям.
Я могу отобразить все 4 поля ввода, а также окно выходного сообщения, но цикл не будет отображаться. Я пытаюсь сохранить расчет цикла в переменной, но понятия не имею, как это сделать. Помогите, пожалуйста. Я в отчаянии.
Вот мой код: `
Sub PaymentScheduleCalculator()
Dim PV As Single '10000
Dim years As Single '2
Dim frequency As Double '12
Dim rate As Variant '4% APR
Dim Ppmt As Double
Dim Ipmt As Double
Dim Pmt As Single 'for pmt after each year
Dim i As Integer 'designation for loop
Dim Temp As Integer
Dim TempVars!
For i = 1 To n * frequency
Pmt = PV * rate / frequency
TempVars! = Temp & vbNewLine & i & _
vbTab & FormatCurrency(PV, 2) & _
vbTab & FormatCurrency(Pmt, 2) & _
vbTab & FormatCurrency(Ipmt, 2) & _
vbTab & FormatCurrency(-Ipmt, 2)
PV = PV - Pmt + Ipmt
Next i
PV = InputBox("How much money do you want to borrow?", "Payment Calculator", 10000)
years = InputBox("If you borrow " & FormatCurrency(PV) & " - how many years do want to borrow the money for?", "Payment Calculator", 2)
rate = InputBox("If you borrow " & FormatCurrency(PV) & " for " & years & " years, " & "what interest rate are you paying?", "Payment Calculator", 0.04)
If Right(rate, 1) = "%" Then
rate = Val(Left(rate, Len(rate) - 1) / 100)
Else
rate = rate
End If
frequency = InputBox("If you borrow " & FormatCurrency(PV) & " at " & FormatPercent(rate) & "," & " for " & years & " years, " & _
"how many payment intervals are there per year?", "Payment Calculator", 12)
'runs fine until here but does not display the loop
MsgBox "Loan Amount " & FormatCurrency(PV) & _
vbNewLine & "Number of Payments " & years * frequency & _
vbNewLine & "Interest Rate " & FormatPercent(rate) & _
vbNewLine & _
vbNewLine & "PMT # " & vbTab & "Balance " & vbTab & "Payment " & vbTab & "Interest " & vbTab & "Capital " & _
vbNewLine & RepeatCalc, , "Payment Calculator"
End Sub
` У меня такое чувство, что я неправильно обозначаю переменную или вообще не обозначаю, и я не знаю, как это исправить, и это медленно сводит меня с ума.
Поставьте точку останова в строке, где начинается цикл, тогда вы сможете проверить свои переменные, прежде чем продолжить.
подождите - частота - это количество платежей в графике амортизации - поэтому, если кредит составляет 5 лет и два раза в год, будет частота 2, равная 10 платежам. Значение поступает из поля ввода ниже.
по поводу точки останова - работает. вроде все работает, выводит текстовые поля ввода и вывода, а не расчет, который находится внутри цикла. Имеет ли это смысл? Так что, как если бы я мог убрать весь цикл, и он все равно работал бы точно так же, как сейчас, и отображал бы те же окна ввода и вывода сообщений. Так что петля как бы невидима.
Дальше? Тогда нужны начальные значения. Цикл не должен зависеть от значений, которые изменяются внутри цикла.
Цикл не выполняется, потому что frequency * n
равняется нулю, когда доходит до этой строки.
поэтому цикл должен двигаться вниз после «частоты =»? Я просто сделал это, переместил его вниз между частотой и msgbox, и ничего не произошло.
Предположительно, да. Они должны иметь значения, прежде чем вы сможете проверить/использовать их значения. Есть смысл?
Вместо «ничего не произошло» — используйте точки останова — используйте F8 для пошагового выполнения построчно. Проверяйте свои переменные по ходу дела.
Да, это имеет смысл - как и порядок операций. Но это похоже на то, когда я запускаю его, цикл просто пропускается. (Также большое спасибо даже за ответ - я очень ценю это!)
Он пропускает цикл, начинающийся с 1, потому что вы говорите ему остановиться на 0, а 1 больше 0.
ой! это имеет смысл! Так что мне просто изменить «от 1 до nчастоты» на «от 0 до nчастоты»?
Это запустит цикл один раз.... и i
будет равно нулю. Так что, если это то, что является вашим намерением...
слушайте, извините, как говорит мое имя пользователя, я нуб. это мое первое знакомство с vba и/или кодированием в целом - я понятия не имею, что делаю. Есть ли способ заглушить это, чтобы я понял, где я ошибаюсь? Я понимаю, что перепутал порядок операций, в этом есть смысл, но я не понимаю, где я ошибаюсь с циклом.
learn.microsoft.com/en-us/office/vba/language/reference/…
Что это TempVars!
? Красиво объявляйте переменные. Dim TempVars As String
и используйте Debug.Print TempVars
сразу после, если вы хотите увидеть, что происходит в цикле. Переместите цикл в место после того, как вы собрали значения из полей ввода после строки runs fine until...
. Никакое другое значение, кроме начального 0, никогда не присваивается Ipmt
: разберитесь. Используйте As Integer
для целых чисел. Не уверен, что n
должен быть, но years
выглядит как кандидат. Используйте Option Explicit
в верхней части модуля, чтобы определить необъявленные переменные.
Да, я понял, что ошибся с объявлением переменных, и braX вчера тоже указал на это, я просто не знал, как это исправить. Спасибо, что нашли время ответить. Я очень ценю это.
В вашем коде есть несколько ошибок... как указывали и другие.
Во-первых, вы хотите запустить цикл For...next
, используя
For i = 1 To n * frequency
'some code
next
Цикл запускается до того, как этим переменным «n» и «частота» будет присвоено значение. Хотя вы намеревались установить «частоту» с помощью поля ввода, «n» нигде не установлено и, следовательно, всегда будет равно 0. Таким образом, в результате цикл выглядит следующим образом:
For i = 1 To 0 * 12 'which results in the loop not running at all
'some code
next
Итак, правильно установите «n» на то, что ему нужно, или предоставьте диалог ввода для него.
Более того, фактическое назначение этого цикла — расширить отображаемый текст в окне сообщения.
Если вы хотите это сделать, вам нужно будет сначала начать строить строку. В соответствии с вашим кодом ваш текст должен начинаться с:
"Loan Amount " & FormatCurrency(PV) & _
vbNewLine & "Number of Payments " & years * frequency & _
vbNewLine & "Interest Rate " & FormatPercent(rate) & _
vbNewLine & _
vbNewLine & "PMT # " & vbTab & "Balance " & vbTab & "Payment " & vbTab & "Interest " & vbTab & "Capital "
Итак, если вы присвоите этот текст переменной, вы можете расширить текст с помощью цикла, например:
Dim msgText As String
msgText = "Loan Amount " & FormatCurrency(PV) & _
vbNewLine & "Number of Payments " & years * frequency & _
vbNewLine & "Interest Rate " & FormatPercent(rate) & _
vbNewLine & _
vbNewLine & "PMT # " & vbTab & "Balance " & vbTab & "Payment " & vbTab & "Interest " & vbTab & "Capital "
'now the loop extends 'msgText'
For i = 1 To n * frequency
Pmt = PV * rate / frequency
msgText = msgText & vbNewLine & Str(i) & _
vbTab & FormatCurrency(PV, 2) & _
vbTab & FormatCurrency(Pmt, 2) & _
vbTab & FormatCurrency(Ipmt, 2) & _
vbTab & FormatCurrency(-Ipmt, 2)
PV = PV - Pmt + Ipmt
Next i
msgText = msgText & vbNewLine & RepeatCalc
Как только это будет завершено, вся строка будет содержаться в переменной msgText
Затем вы можете инициировать MsgBox
с этим текстом.
MsgBox msgText, vbOKOnly, "Payment Calculator"
Еще одна вещь: у вас есть InputBox для rate
, и вы, кажется, пытаетесь удалить знак «%» в конце строки на случай, если кто-то вставит процент со знаком. (хорошая мысль сама по себе..:-))
Хотя это работает, в итоге получается переменная типа String
, и, поскольку rate
объявляется как Variant
, с этим проблем нет...
Но это испортит ваш расчет в вашем цикле For..next
, так как Pmt = PV * rate / frequency
может работать только с использованием значений (например, Double\Integer и т. д.)
Что вам нужно сделать, так это объявить rate
как Double
и убедиться, что результат вашего удаления «%» будет преобразован в значение Double
с помощью, например, использования CDbl(Val(Left(rate, Len(rate) - 1) / 100))
Итак, ваш код с некоторыми поправками должен выглядеть примерно так, как показано ниже. Имейте в виду, что вам, возможно, придется убедиться, что все переменные (включая «n») установлены правильно, чтобы обеспечить правильность расчета. Как, например, Ipmt
нигде не вычисляется...
Измененный код:
Sub PaymentScheduleCalculator()
Dim PV As Single '10000
Dim years As Single '2
Dim frequency As Double '12
Dim rate As Double '4% APR
Dim strRate As String
Dim Ppmt As Double
Dim Ipmt As Double
Dim Pmt As Single 'for pmt after each year
Dim i As Integer 'designation for loop
Dim Temp As Integer
n = 1 'has to be properly set to relevant value?
PV = InputBox("How much money do you want to borrow?", "Payment Calculator", 10000)
years = InputBox("If you borrow " & FormatCurrency(PV) & " - how many years do want to borrow the money for?", "Payment Calculator", 2)
strRate = InputBox("If you borrow " & FormatCurrency(PV) & " for " & years & " years, " & "what interest rate are you paying?", "Payment Calculator", 0.04)
If Right(strRate, 1) = "%" Then
rate = CDbl(Val(Left(strRate, Len(strRate) - 1) / 100))
Else
rate = CDbl(strRate)
End If
frequency = InputBox("If you borrow " & FormatCurrency(PV) & " at " & FormatPercent(rate) & "," & " for " & years & " years, " & _
"how many payment intervals are there per year?", "Payment Calculator", 12)
Dim msgText As String
msgText = "Loan Amount " & FormatCurrency(PV) & _
vbNewLine & "Number of Payments " & years * frequency & _
vbNewLine & "Interest Rate " & FormatPercent(rate) & _
vbNewLine & _
vbNewLine & "PMT # " & vbTab & "Balance " & vbTab & "Payment " & vbTab & "Interest " & vbTab & "Capital "
'now extends the 'msgText' variable
For i = 1 To n * frequency
Pmt = PV * rate / frequency
msgText = msgText & vbNewLine & Str(i) & _
vbTab & FormatCurrency(PV, 2) & _
vbTab & FormatCurrency(Pmt, 2) & _
vbTab & FormatCurrency(Ipmt, 2) & _
vbTab & FormatCurrency(-Ipmt, 2)
PV = PV - Pmt + Ipmt
Next i
msgText = msgText & vbNewLine & RepeatCalc
MsgBox msgText, vbOKOnly, "Payment Calculator"
End Sub
Спасибо вам большое за это! И особенно спасибо за подробное объяснение и помощь в обучении. Я очень ценю это. Я полностью полагал, что n — это просто часть формулы, поэтому я не объявлял его — ух! Это имеет так много смысла сейчас!
С удовольствием, рад, что смог помочь. Если это ответило на ваш вопрос, отметьте ответ как правильный ответ, это поможет ТАК оставаться в курсе, сводя к минимуму вопросы без ответа.
@Excelnoob, кстати, я думаю, что «n» в вашем расчете должно быть значением «годы»? Это имело бы смысл с точки зрения фактического расчета, а также потому, что в вашем коде вы фактически нигде не используете значение «годы»?
Должны ли мы предположить, что
frequency
иn
равны нулю, поскольку вы не придали им значения?For i = 1 to 0
означает, что цикл не будет выполняться.