Меню

Ошибка vba out of stack space

Permalink

Cannot retrieve contributors at this time

title keywords f1_keywords ms.prod ms.assetid ms.date ms.localizationpriority

Out of stack space (Error 28)

vblr6.chm1000028

vblr6.chm1000028

office

ce345551-ad57-1120-546a-239d144c330a

06/08/2017

medium

The stack is a working area of memory that grows and shrinks dynamically with the demands of your executing program. This error has the following causes and solutions:

  • You have too many active Function, Sub, or Property procedure calls. Check that procedures aren’t nested too deeply. This is especially true with recursive procedures, that is, procedures that call themselves. Make sure recursive procedures terminate properly. Use the Calls dialog box to view which procedures are active (on the stack).

  • Your local variables require more local variable space than is available.

    Try declaring some variables at the module level instead. You can also declare all variables in the procedure static by preceding the Property, Sub, or Function keyword with Static. Or you can use the Static statement to declare individual Static variables within procedures.

  • You have too many fixed-length strings. Fixed-length strings in a procedure are more quickly accessed, but use more stack space than variable-length strings, because the string data itself is placed on the stack. Try redefining some of your fixed-length strings as variable-length strings. When you declare variable-length strings in a procedure, only the string descriptor (not the data itself) is placed on the stack. You can also define the string at module level where it requires no stack space. Variables declared at module level are Public by default, so the string is visible to all procedures in the module.

  • You have too many nested DoEvents function calls. Use the Calls dialog box to view which procedures are active on the stack.

  • Your code triggered an event cascade. An event cascade is caused by triggering an event that calls an event procedure that’s already on the stack. An event cascade is similar to an unterminated recursive procedure call, but it’s less obvious, since the call is made by Visual Basic rather than by an explicit call in your code. Use the Calls dialog box to view which procedures are active (on the stack).

To display the Calls dialog box, select the Calls button to the right of the Procedure box in the Debug window or choose the Calls command. For additional information, select the item in question and press F1 (in Windows) or HELP (on the Macintosh).

[!includeSupport and feedback]

 

denis76

Пользователь

Сообщений: 22
Регистрация: 19.02.2013

#1

31.05.2016 15:23:02

Добрый день!

Столкнулся неожиданно с такой ситуацией: при вызове вложенной процедуры в VBA появляется указанное сообщение об ошибке:

Код
... out of stack space...

Собственно говоря, процедура довольно громоздкая, обрабатывает и пересчитывает массивы данных размером примерно 10000*200 ячеек… хотя работала до сего времени вполне нормально…

Собственно говоря, в чем здесь может быть причина появления такого сообщения:
— много переменных?
— большой размер переменных (массивов)?
— большое кол-во вызовов функций?
— вызов функций с аргументами в виде больших массивов (используется несколько раз такое)?

Какие тут способы решения имеются — может, надо как-то уничтожать переменные после использования, очищать стек — как это сделать?… Может, какие-то параметры в реестре надо подправить или еще где?.. Что известно по данному вопросу уважаемым специалистам?..

Спасибо заранее…

 

Sanja

Пользователь

Сообщений: 14837
Регистрация: 10.01.2013

Собственно говоря почему-бы не в

ПОИСК

?

Согласие есть продукт при полном непротивлении сторон.

 

denis76

Пользователь

Сообщений: 22
Регистрация: 19.02.2013

#3

31.05.2016 15:46:06

Хорошо…

Вот, смотрю, там 5 случаев указано, к моему может, видимо, это относиться:

Цитата
…Your local variables require more local variable space than is available.Try declaring some variables at the module level instead. You can also declare all variables in the procedure static by preceding the Property,Sub, or Function keyword with Static. Or you can use the Static statement to declare individual Static variables within procedures…

Все равно странно, больше всего ведь места массивы занимают, но не на них ошибка вылезает…
И как, получается, каждую что ли переменную надо в начале модуля объявлять заранее? А потом что, уничтожать надо или как?

Еще вот, смотрю в редакторе VBA — там такая закладка Call stack — почему-то в ней список в 50 с лишним процедур, когда у меня столько их одновременно не вызывается… и некоторые повторяются почему-то…
И вообще, как-то размер и заполненность этого стека можно ли узнать и регулировать?..

 

Нет файла — нет идей, что тут не понятно.

 

Игорь

Пользователь

Сообщений: 3615
Регистрация: 23.12.2012

Причина — большой размер массивов
10,000*200 = 2 млн ячеек — таких массивов много в памяти Excel не удержит

Как вариант еще одной причины, — вызов функций с аргументами в виде больших массивов
Массивы такие надо передавать как byRef в другие функции
(ну и вообще сделать в коде так, чтобы не создавались лишние копии такого большого массива, — а то памяти не хватит)

 

denis76

Пользователь

Сообщений: 22
Регистрация: 19.02.2013

#6

31.05.2016 16:12:19

Цитата
kalbasiatka написал: Нет файла — нет идей, что тут не понятно.

Глубоко сомневаюсь, что данный файл кому-то разбирать охота будет… но думаю, что основные варианты можно предположить и без его досконального исследования…

 

denis76

Пользователь

Сообщений: 22
Регистрация: 19.02.2013

#7

31.05.2016 16:14:51

Цитата
Игорь написал: Причина — большой размер массивов

Про массивы — да, все так, но ведь он не выдает Out of memory (это прошло с установкой 64-битной версии), а вот на стек именно ругается-то… А каков этот стек и его допустимый размер — мне пока неведомо…

 

denis76

Пользователь

Сообщений: 22
Регистрация: 19.02.2013

#8

31.05.2016 16:17:04

Цитата
Игорь написал: Массивы такие надо передавать как byRef в другие функции

Так вроде бы по умолчанию они так и передаются, нет разве?.. И вроде как лишних копий не делается…

Изменено: denis7601.06.2016 22:06:07

 

Hugo

Пользователь

Сообщений: 23101
Регистрация: 22.12.2012

Мне стека не хватало пару раз из-за рекурсии.

 

denis76

Пользователь

Сообщений: 22
Регистрация: 19.02.2013

Разобрался, в чем дело… когда начал код улучшать, нашел место, где процедуры вызывают одна другую поочередно…

 

Hugo

Пользователь

Сообщений: 23101
Регистрация: 22.12.2012

#11

01.06.2016 12:07:48

Т.е. тоже виновата рекурсия?

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim b As Integer
    b = 0

    Dim cell As Range
    Dim rgn As Range

    Set rgn = Range("f2:f200")

    For Each cell In rgn
        If IsEmpty(cell) = False Then
            b = b + 1
        End If
    Next

    Range("d2").Value = b
End Sub

Hi, I met a problem when trying to run the following piece of Excel VBA code. A message box will pop out and say there is a

«out of stack space»

problem to line Set rgn = range("f2:f200"), then another message box will pop out and say

«method ‘value’ of object ‘range’ failed»

I don’t know what is wrong… Thank you very much for helping.

Community's user avatar

asked Jun 13, 2017 at 7:36

Jiaming Yang's user avatar

The problem is that you are changing cells in a Change event, which will trigger the event again, and again, and again…

You need to disable events temporarily:

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim b As Integer
    b = 0

    Dim cell As Range
    Dim rgn As Range

    Set rgn = Range("f2:f200")

    For Each cell In rgn
        If IsEmpty(cell) = False Then
            b = b + 1
        End If
    Next
    Application.Enableevents = False
    Range("d2").Value = b
    Application.Enableevents = True
End Sub

answered Jun 13, 2017 at 7:42

Rory's user avatar

RoryRory

32.3k5 gold badges30 silver badges34 bronze badges

2

  • Remove From My Forums
  • Question

  • Hi All,

    I created a spreadsheet in excel 2013-VB v7.1 and had no issues with the code i created. when i try to run it i get the error code ’28’ and i have no idea to solve this.

    Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal A_Scound As Long) 
    
    Public Sub ScheduleJoodi_API() 
        ActiveWorkbook.UpdateLink Name:=ActiveWorkbook.LinkSources 
        DoEvents 
        Sleep (100) 
        ActiveWorkbook.UpdateLink Name:=ActiveWorkbook.LinkSources 
        Joodi 
    Exit Sub 
    End Sub 
    
    
    Sub Joodi() 
        If Sheet1.Range("A1").Value = 1 Then 
        Application.Calculation = False 
        Sheet1.Range("A2:A4").Copy 
        Sheet1.Range("B2").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False 
        Application.CutCopyMode = False 
        Range("B1").Select 
        Application.Calculation = True 
     End If 
        Call ScheduleJoodi_API 
    End Sub 

    If anyone could help out it would be greatly appreciated.

    Thanks in advance,

    Alex

Answers

  • You have two procedures; each calls the other one. As a result, you keep on pushing procedure calls onto the call stack ad infinitum — or rather, until you run out of stack space.

    Try something like this instead:

    Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal A_Scound As Long)
    
    Public Sub ScheduleJoodi_API()
        ActiveWorkbook.UpdateLink Name:=ActiveWorkbook.LinkSources
        DoEvents
        Sleep 100
        ActiveWorkbook.UpdateLink Name:=ActiveWorkbook.LinkSources
    End Sub
    
    Sub Joodi()
        If Sheet1.Range("A1").Value = 1 Then
            Application.Calculation = False
            Sheet1.Range("A2:A4").Copy
            Sheet1.Range("B2").PasteSpecial Paste:=xlPasteValues
            Application.CutCopyMode = False
            Range("B1").Select
            Application.Calculation = True
        End If
        Call ScheduleJoodi_API
        Application.OnTime Now + TimeSerial(0, 1, 0), "Joodi"
    End Sub


    Regards, Hans Vogelaar

    • Marked as answer by

      Friday, December 14, 2012 12:35 PM

  • You can combine the two procedures, if you wish:

    Sub Joodi()
        If Sheet1.Range("A1").Value = 1 Then
            Application.Calculation = False
            Sheet1.Range("A2:A4").Copy
            Sheet1.Range("B2").PasteSpecial Paste:=xlPasteValues
            Application.CutCopyMode = False
            Range("B1").Select
            Application.Calculation = True
        End If
        ActiveWorkbook.UpdateLink Name:=ActiveWorkbook.LinkSources
        DoEvents
        Sleep 100
        ActiveWorkbook.UpdateLink Name:=ActiveWorkbook.LinkSources
        Application.OnTime Now + TimeSerial(0, 1, 0), "Joodi"
    End Sub

    When you run Joodi, it will run every minute (or at whatever interval you set in Application.OnTime).


    Regards, Hans Vogelaar

    • Marked as answer by
      Quist Zhang
      Friday, December 14, 2012 12:35 PM

I have a very simple macro in an Excel sheet, to allows users to recalculate.

I have no other macros/code in the workbook, and only this work book open

Sub Calculate()
    Calculate
End Sub

This is activated by a button.

However, when pressed I get two error boxes, see image.

What does Out of stack space mean ?
And how do I resolve this issue ?
enter image description here

I have looked on this website:

https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/out-of-stack-space-error-28

It says I may have too many funtions ??
This macro used to work fine, and it is hardly doing a lot so cannot understand the issue.

I am able to calculate the sheet using the option under the formulas tab.

asked Nov 29, 2018 at 10:49

PeterH's user avatar

PeterHPeterH

7,30718 gold badges53 silver badges79 bronze badges

4

The function you have define is recursive, calling itself unconditionally until the stack is filled with all the calls.

You should change the name of your subroutine, eg:-

Sub Calc()
    Calculate
End Sub

If you link Calc() to the button, you avoid any recursion.

answered Nov 29, 2018 at 11:07

AFH's user avatar

AFHAFH

17k3 gold badges30 silver badges48 bronze badges

4

You’re calling Calculate inside of Calculate. Every call to Calculate causes another call to Calculate, which will then call Calculate… Then eventually you get that error when the stack fills up.

answered Nov 29, 2018 at 11:07

Enigman's user avatar

EnigmanEnigman

7773 silver badges7 bronze badges

3

t17fenics

0 / 0 / 0

Регистрация: 11.03.2015

Сообщений: 4

1

11.03.2015, 12:47. Показов 3414. Ответов 7

Метки нет (Все метки)


Добрый день.
Разбираюсь с формами VBA, написал следующий код.
Он выводит квадратный объект перемещающийся в замкнутой области по заданному алгоритму.
Скорость движения можно менять, так же выводится дополнительная информация(скорость, координаты, размеры рабочей области)
Проблема в том, что спустя несколько минут(3-5) после запуска программа вываливается в out of stack.
Никакие данные кроме отскоков не накапливаются. На момент переполнения буфера на максимальной скорости количество отскоков доходит до ~6000.

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
Public Sub Form_Run()
 
''размеры рабочей области
x = 300
y = 300
 
 
wt = 20 ''начальная задержка между сдвигами(обратнопропорциональна скорости движения объекта
 
sh = 0.6 '' методом экспериментов установлено, что минимальный сдвиг объекта возможен на 0.50000000000000001(видимо в бесконечном периуде)
 
pong = -1 ''Счетчик отскоков
 
''Формирование формы
UserForm2.Frame1.Visible = True
UserForm2.TextBox1.Visible = False
UserForm2.TextBox2.Visible = False
UserForm2.Label1.Visible = True
UserForm2.Label2.Visible = True
UserForm2.Label3.Visible = True
UserForm2.Label4.Visible = True
 
UserForm2.Height = x
UserForm2.Width = y
 
UserForm2.Frame1.top = 1
UserForm2.Frame1.left = 1
UserForm2.Frame1.Height = UserForm2.Height - 161 ''100 на рабочую область, 21 на заголовки и бордюры
UserForm2.Frame1.Width = UserForm2.Width - 7 ''7 на бордюры
''методом экспериментов установлено, что рамка равна 7(3,5 на сторону), заголовок равен 14
 
 
UserForm2.CommandButton1.Width = 20
UserForm2.CommandButton1.Height = 20
UserForm2.CommandButton1.caption = ""
UserForm2.CommandButton1.top = UserForm2.Frame1.top - 1
UserForm2.CommandButton1.left = UserForm2.Frame1.left - 1
 
UserForm2.CommandButton2.Width = 40
UserForm2.CommandButton2.Height = 30
UserForm2.CommandButton2.caption = pong & vbNewLine & "stop"
UserForm2.CommandButton2.top = UserForm2.Frame1.Height + 100
UserForm2.CommandButton2.left = UserForm2.Frame1.Width / 2 - UserForm2.CommandButton2.Width / 2
 
UserForm2.Label1.Width = 30
UserForm2.Label1.Height = 20
UserForm2.Label1.top = UserForm2.Frame1.Height + 10
UserForm2.Label1.left = UserForm2.Frame1.left + 10
UserForm2.Label1.caption = UserForm2.CommandButton1.left
 
UserForm2.Label2.Width = 30
UserForm2.Label2.Height = 20
UserForm2.Label2.top = UserForm2.Frame1.Height + 40
UserForm2.Label2.left = UserForm2.Frame1.left + 10
UserForm2.Label2.caption = UserForm2.CommandButton1.top
 
UserForm2.Label3.Width = 150
UserForm2.Label3.Height = 20
UserForm2.Label3.top = UserForm2.Frame1.Height + 70
UserForm2.Label3.left = UserForm2.Frame1.left + 10
UserForm2.Label3.caption = UserForm2.Frame1.Width & " X " & UserForm2.Frame1.Height & "(" & UserForm2.Width & " X " & UserForm2.Height & ")"
 
UserForm2.Label4.Width = 30
UserForm2.Label4.Height = 20
UserForm2.Label4.top = UserForm2.Label2.top
UserForm2.Label4.left = UserForm2.Label2.left + UserForm2.Label2.Width + 20
UserForm2.Label4.caption = wt
 
UserForm2.SpinButton1.top = UserForm2.Label1.top
UserForm2.SpinButton1.left = UserForm2.Label1.left + UserForm2.Label1.Width + 20
 
UserForm2.Show
 
''запуск цикла
bottom_right
 
End Sub
 
 
 
Sub SleepVB(mSeconds)
 
DoEvents
Sleep mSeconds
 
End Sub
 
 
 
Public Sub repaint()
''Процедура обновления содержимого формы. Выполняется после каждого пересчета координат объекта
check
UserForm2.Label1.caption = UserForm2.CommandButton1.top
UserForm2.Label2.caption = UserForm2.CommandButton1.left
UserForm2.Label4.caption = wt
UserForm2.CommandButton2.caption = pong & vbNewLine & "stop"
 
''Процедура задержки
SleepVB wt
 
End Sub
 
 
Public Sub bottom_right()
''Следующие 4 процедуры проссчитывают движение объекта
Test1
 
Do While UserForm2.CommandButton1.top < UserForm2.Frame1.Height - 24 ''размеры кнопки 20+ бордюр 2 с каждой стороны
    UserForm2.CommandButton1.top = UserForm2.CommandButton1.top + sh
    UserForm2.CommandButton1.left = UserForm2.CommandButton1.left + sh
    repaint
    
    If UserForm2.CommandButton1.left > UserForm2.Frame1.Width - 25 Then
        bottom_left
    End If
Loop
 
top_right
 
End Sub
 
 
Public Sub top_right()
 
Test1
 
Do While UserForm2.CommandButton1.left < UserForm2.Frame1.Width - 24  ''226
    UserForm2.CommandButton1.top = UserForm2.CommandButton1.top - sh
    UserForm2.CommandButton1.left = UserForm2.CommandButton1.left + sh
    repaint
    
    If UserForm2.CommandButton1.top < UserForm2.Frame1.top Then
        bottom_right
    End If
Loop
 
top_left
 
End Sub
 
Public Sub top_left()
 
Test1
 
Do While UserForm2.CommandButton1.top > UserForm2.Frame1.top - 1
    
    UserForm2.CommandButton1.top = UserForm2.CommandButton1.top - sh
    UserForm2.CommandButton1.left = UserForm2.CommandButton1.left - sh
    repaint
    
    If UserForm2.CommandButton1.left < UserForm2.Frame1.left Then
        top_right
    End If
 
Loop
 
bottom_left
 
End Sub
 
Public Sub bottom_left()
 
Test1
 
Do While UserForm2.CommandButton1.left > UserForm2.Frame1.left - 1
 
    UserForm2.CommandButton1.top = UserForm2.CommandButton1.top + sh
    UserForm2.CommandButton1.left = UserForm2.CommandButton1.left - sh
    repaint
    
    If UserForm2.CommandButton1.top > UserForm2.Frame1.Height - 25 Then
        top_left
    End If
 
Loop
 
bottom_right
 
End Sub

Подскажите пожалуйста, в чем может быть проблема?

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



Night Ranger

Заблокирован

11.03.2015, 12:57

2

Вы не пробывали перевести ваше сообщение и понять что оно озночает ?
(Недостаточно места в памяти)



0



Апострофф

Заблокирован

11.03.2015, 13:15

3

Цитата
Сообщение от t17fenics
Посмотреть сообщение

check

Цитата
Сообщение от t17fenics
Посмотреть сообщение

Test1

Что означают эти загадочные буквосочетания?



0



0 / 0 / 0

Регистрация: 11.03.2015

Сообщений: 4

11.03.2015, 13:20

 [ТС]

4

Сорри, не вычистил при публикации.
Не обращайте внимание, это дополнительные процедуры. Проблема существовала с самого раннего этапа написания кода, когда этих процедур еще не было.
Там есть еще код, просто удалил его из публикации, чтоб не грузить, оставил каркас. Проблема именно в опубликованном коде, проверено 20 раз уже.



0



Апострофф

Заблокирован

11.03.2015, 13:24

5

Цитата
Сообщение от t17fenics
Посмотреть сообщение

out of stack

происходит обычно при непродуманном рекурсивном вызове процедур друг из друга, что наглядно демонстрирует ваш случай.



0



0 / 0 / 0

Регистрация: 11.03.2015

Сообщений: 4

11.03.2015, 13:32

 [ТС]

6

Хм. ошибка проявляется только после 6000 запусков этих процедур.
я так понимаю экземпляры процедуры остаются в памяти?
может быть как то можно прибить процедуру при переходе в следующую?



0



Night Ranger

Заблокирован

11.03.2015, 13:42

7

Воспользуйтесь ключевыми словами .. is Nothing, если не иностранец..



0



0 / 0 / 0

Регистрация: 11.03.2015

Сообщений: 4

11.03.2015, 14:23

 [ТС]

8

Вобщем осознал корень проблемы. Спасибо Апострофф

Код просчитывающий движение надо как то по другому писать. без бесконечного вызова процедур друг из друга.



0



0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

А вот еще интересные материалы:

  • Яшка сломя голову остановился исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного где ошибка
  • Ошибка usb 43 как исправить проблему
  • Ошибка vba method range of object global failed