С Новым годом! Форум программистов, компьютерный форум, киберфорум
Visual Basic
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
1384 / 838 / 91
Регистрация: 08.02.2017
Сообщений: 3,517
Записей в блоге: 1

End With по требованию

06.10.2024, 08:52. Показов 3036. Ответов 52
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
В одном коде надо было перебирать элементы массива UDT и при определенных условиях "выпрыгнуть" из цикла, а после цикла при определенных условиях происходит редим этого массива, но обнаружилась одна проблемка с использованием оператора With в таком сценарии. Упрощенно проблемму можно воспроизвести таким кодом
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Private Type tpNode
    Val As Long
End Type
 
Sub TestWith()
    Dim i&, Nodes() As tpNode
    
    ReDim Nodes(5) As tpNode
    
    Do
        With Nodes(2)
            .Val = 1
            Exit Do
        End With
    Loop
    
    ReDim Preserve Nodes(6)    
End Sub
При выполнении данного кода после цикла выскочит ошибка "This array is fixed or temporarily locked". Она возникает по причине того, что оператор With захватывает элемен массива и блокирует массив от изменения размерности. Поскольку выход из цикла происходит до закрытия With, блокировка массива не снимается. В идеальном случае нужно было выходить из цикла после End With, но в том коде все действия происходят в условном операторе, помещенном внутри With. Здача данной темы отгадать, 1) как я реши эту пролему (или предложить свое решение); 2) то же самое, но с использованием цикла For )
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
06.10.2024, 08:52
Ответы с готовыми решениями:

Excel 2013 32-bit URLDownloadToFile пишет "Compile error: only comment may appear after End Sub End Function or End Prop
Добрый день! перепробовал все варианты и не вызывается функция URLDownloadToFile: пишет "Compile error: only comment may appear...

Требуется Web-разработчик (Front end/Back end) Санкт-Петербург
Обязанности: • Основная задача: бек энд разработка (организация REST-API сервисов и взаимодействие с БД (crud-операции) на python),...

Java Developer (front-end + back-end); Chicago,IL; H1B Sponsorship is available!
Valdi Group LLC is a Chicago based software development and software testing consulting firm that successfully delivering elegant and...

52
428 / 333 / 61
Регистрация: 29.06.2019
Сообщений: 493
06.10.2024, 09:55
Самое очевидное и простое решение - выкинуть With из кода как лишнее образование.
3
1384 / 838 / 91
Регистрация: 08.02.2017
Сообщений: 3,517
Записей в блоге: 1
06.10.2024, 10:04  [ТС]
Цитата Сообщение от SergioJek Посмотреть сообщение
Самое очевидное и простое решение - выкинуть With из кода как лишнее образование.
При этом произойдет заметное замедление кода. Всякий раз, когда мы обращаемся к элементу массива (Nodes(i)) происходит вычисление указателя элемента по индексу, если у нас будет 2 обращения к одному и тому же элементу, то это время удваиваивается, если 3, то утраивается, в каждой итерации, а итераций может быть миллионы.
0
Модератор
10048 / 3894 / 883
Регистрация: 22.02.2013
Сообщений: 5,847
Записей в блоге: 79
06.10.2024, 10:19
testuser2, это баг компилятора. Насколько я помню если выйти из With не через End With то элемент так и останется залоченным.
1
1384 / 838 / 91
Регистрация: 08.02.2017
Сообщений: 3,517
Записей в блоге: 1
06.10.2024, 10:21  [ТС]
Цитата Сообщение от The trick Посмотреть сообщение
это баг компилятора
Кстати в подпрограмме если после Return нету такого бага
0
Модератор
10048 / 3894 / 883
Регистрация: 22.02.2013
Сообщений: 5,847
Записей в блоге: 79
06.10.2024, 10:24
testuser2, я не проверял, но попробуй вручную вызвать SafeArrayUnlock, Но хз как поведет при выходе из процедуры, т.к. при выходе будет вызван Unlock.
1
1384 / 838 / 91
Регистрация: 08.02.2017
Сообщений: 3,517
Записей в блоге: 1
06.10.2024, 10:51  [ТС]
The trick, я придумал как сделать без вызова Api, но может быть это бы помогло.
0
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
06.10.2024, 13:08
Цитата Сообщение от The trick Посмотреть сообщение
Насколько я помню если выйти из With не через End With
может через Exit With

Добавлено через 37 секунд
а Exit With вообще есть?

Добавлено через 1 минуту
Цитата Сообщение от testuser2 Посмотреть сообщение
а итераций может быть миллионы
даже если и миллионы, не думаю что работа твоей программы сильно замедлится, максимум на пол секунды дольше подождёшь и всё

Добавлено через 1 минуту
ты приведи доказательства мне по скоростям с реальными примерами и с доказательством необходимости этого With.
Соглашусь с SergioJek что скорее всего With просто напросто не нужен вообще.

Добавлено через 3 минуты
А вот кстати и решение:

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Option Explicit
Dim Nodes() As tpNode
 
Private Type tpNode
    Val As Long
End Type
 
Sub TestWith()
    ReDim Nodes(5) As tpNode
    
    Do
        With Nodes(2)
            .Val = 1
            Exit Sub
        End With
    Loop
End Sub
 
Private Sub Form_Load()
    TestWith
    ReDim Preserve Nodes(6) ' Вызвать после процедуры, а из процедуры делать выход в конструкции With
End Sub
Добавлено через 57 секунд
Exit With не существует, я проверил

Добавлено через 7 минут
The trick, SafeArrayUnlock не помог кстати
2
1384 / 838 / 91
Регистрация: 08.02.2017
Сообщений: 3,517
Записей в блоге: 1
06.10.2024, 13:38  [ТС]
Даю подсказку: я использовал Goto и расположил With не внутри, а снаруже цикла
0
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
06.10.2024, 13:49
testuser2, я тебе дал ответ уже как всё работает
0
1384 / 838 / 91
Регистрация: 08.02.2017
Сообщений: 3,517
Записей в блоге: 1
06.10.2024, 16:15  [ТС]
Лучший ответ Сообщение было отмечено HackerVlad как решение

Решение

HackerVlad, это не подходит, надо редимить в той же процедуре после цикла с выходом из With

Добавлено через 20 минут
Итак, вот мое решение. Сделал несколько итераций, чтобы было понятней, как это работает
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
WithElem:
    With Nodes(i)
      GoTo Cycle
      Do
          GoTo WithElem
Cycle:
          i = i + 1
          If i < 5 Then
              .Val = i
          Else: Exit Do
          End If
      Loop
    End With
    
    ReDim Preserve Nodes(6)
Добавлено через 9 минут
Есть еще вариант вместо Exit Do использовать флаг выхода из цикла, но тогда при каждой итерации будет проверка флага, но, что-то подсказывает, что 2 перехода на метки будут быстрей чем одна проверка флага

Добавлено через 20 минут
А так будет работать с циклом For. У цикла For нужно обязательно пройти "шапку", чтобы цикл запустился
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    GoTo StartCycle
WithNode:
    With Nodes(i)
      GoTo Cycle
StartCycle:
      For i = 1 To 5
          GoTo WithNode
Cycle:
          If i < 5 Then
          .Val = i
          Else: Exit For
          End If
      Next
    End With
Добавлено через 13 минут
Тут можно заметить, что открытий With в цикле происходит много, в то время как закрытие одно в обоих случаях, однако это нормально работает, что наверное можно объяснить тем, что для одного итого же With используется всегда одна и та же веменная переменная и именно освобождение этой переменной играет роль.

Добавлено через 5 минут
Причем эта переменная, наверняка, работает по принципу ByRef-ссылки и ее можно использовать для работы с указателями, только вопрос как найти ее указатель..

Добавлено через 39 минут
Кажись нашел, она идет сразу перед стеком аргументов..

Добавлено через 1 минуту
Точнее не аргументов, а переменных процедуры

Добавлено через 7 минут
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Sub TestWith2(Optional ByVal lp0&)
    Dim Nodes(2) As tpNode, Node As tpNode, pTmp&
    pTmp = VarPtr(pTmp) - 4
    
    With Node
        CopyMemory ByVal pTmp, VarPtr(Nodes(0)), 4
        .Val = 1
        CopyMemory ByVal pTmp, VarPtr(Nodes(1)), 4
        .Val = 2
        CopyMemory ByVal pTmp, VarPtr(Nodes(2)), 4
        .Val = 3
    End With
    Debug.Print Nodes(0).Val & vbCr & _
                Nodes(1).Val & vbCr & _
                Nodes(2).Val
End Sub
Добавлено через 20 минут
Если несколько with-ов, то первый будет по адресу VarPtr(pTmp) - 4, второй VarPtr(pTmp) - 8 и т.д.

Добавлено через 6 минут
Который первы в коде (самый верхний With) будет VarPtr(pTmp) - 4, а дальше которые ниже по коду -8, -12
0
1384 / 838 / 91
Регистрация: 08.02.2017
Сообщений: 3,517
Записей в блоге: 1
07.10.2024, 05:08  [ТС]
Цитата Сообщение от testuser2 Посмотреть сообщение
2 перехода на метки будут быстрей чем одна проверка флага
Неа, ни какой разницы такой код стольже быстрый как из с метками
Visual Basic
1
2
3
4
5
6
7
8
9
      Do
          With Nodes(i)
            i = i + 1
            If i < 5 Then
                .Val = i
            Else: stopIter = True
            End If
          End With
      Loop Until stopIter = True
Добавлено через 13 минут
Разница есть но всего 2-5% на обработке 1 млн.
Кликните здесь для просмотра всего текста
2,888672
2,859375
2,875

2,753906
2,734375
2,734375


Добавлено через 3 часа 8 минут
Цитата Сообщение от testuser2 Посмотреть сообщение
А так будет работать с циклом For
Там не правильно, вот прально
Visual Basic
1
2
3
4
5
6
7
8
9
    For i = 1 To 5
        With Nodes(i)
          If i < 5 Then
              .Val = i
          Else
              i = 5 'Exit For
          End If
        End With
    Next
1
 Аватар для Mikle Quits
762 / 279 / 16
Регистрация: 21.01.2023
Сообщений: 408
07.10.2024, 09:34
Хм... век живи - век учись. Я до сих пор считал, что With - это просто синтаксический сахар, сокращение длинных выражений. Для того, чтобы повысить быстродействие, убрав постоянные расчёты индексов, применял процедуры.
2
1384 / 838 / 91
Регистрация: 08.02.2017
Сообщений: 3,517
Записей в блоге: 1
08.10.2024, 02:28  [ТС]
Mikle Quits, Как вы сделали такое выделение With в тексте?
Цитата Сообщение от Mikle Quits Посмотреть сообщение
Для того, чтобы повысить быстродействие, убрав постоянные расчёты индексов, применял процедуры.
Фактически можно также считать решением вопроса. Еще можно тело цикла поместить в подпрограмму и выход из подпрограммы (Return) корректно будет завершать With.
0
 Аватар для Mikle Quits
762 / 279 / 16
Регистрация: 21.01.2023
Сообщений: 408
08.10.2024, 08:19
Цитата Сообщение от testuser2 Посмотреть сообщение
Как вы сделали такое выделение With в тексте?
Тег "InLine".
Цитата Сообщение от testuser2 Посмотреть сообщение
Еще можно тело цикла поместить в подпрограмму и выход из подпрограммы
Но это не избавляет от With, а только корректно завершает. Простое перемещение цикла внутрь блока With тоже решает эту проблему, и не нужны устаревшие конструкции.
А процедура именно заменяет With, причём, как удаляет постоянные расчёты индексов, так и сокращает написание выражений.
1
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
08.10.2024, 16:41
Цитата Сообщение от testuser2 Посмотреть сообщение
Return)
в vb6 нет оператора continiue или return
0
1384 / 838 / 91
Регистрация: 08.02.2017
Сообщений: 3,517
Записей в блоге: 1
08.10.2024, 17:55  [ТС]
HackerVlad, Return есть, это секретный оператор, используется с еще одним секретным оператором GoSub, но речь уже его касалась в этой теме. Может пример так себе, но просто для примера как его можно использовать.
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
    GoTo InWith
WithNode:
    With Nodes(i)
Return
InWith:
      
      Do
          GoSub WithNode
          If i < 5 Then
              i = i + 1
              .Val = i
          Else
              Exit Do
          End If
      Loop
      
      l = Rnd * 5
      For i = 1 To 5
          GoSub WithNode
          If i = l Then .Val = l: Exit For
      Next
    
    End With
1
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
08.10.2024, 18:44
странно
0
1384 / 838 / 91
Регистрация: 08.02.2017
Сообщений: 3,517
Записей в блоге: 1
09.10.2024, 04:49  [ТС]
Имхо это удобно, тем, что позволяет некоторые участки процедуры определить подпрограммой (термин из qbasic мне в школе о нравился) и испоизовать в разных частях процедуры. У подпрограмм есть свой стек вызовов и если внутри подпрограммы вызвать другую подпограмму, то она вернется туда, от куда ее вызвали и та из которой вызвали вернется, откуда ее вызвали

Добавлено через 5 минут
Есть еще одно секретное слово в бейсике, как Let, правда оно не имеет особого значения )
0
 Аватар для Mikle Quits
762 / 279 / 16
Регистрация: 21.01.2023
Сообщений: 408
20.11.2024, 09:27
Наткнулся на неприятный баг With.
На форме frmMain есть пикчербокс picScore. Из модуля делаю с ним различные действия:
Visual Basic
1
2
3
4
5
    frmMain.picScore.CurrentX = 2
    frmMain.picScore.CurrentY = 32 * i - 4
    frmMain.picScore.Print PlName(i);
    frmMain.picScore.CurrentX = 216
    frmMain.picScore.Print Trim(Str(PlScore(i)));
Если обрамить это всё в With frmMain.picScore, укорачивается:
Visual Basic
1
2
3
4
5
    .CurrentX = 2
    .CurrentY = 32 * i - 4
    .Print PlName(i);
    .CurrentX = 216
    .Print Trim(Str(PlScore(i)));
Но псевдометод .Print не работает.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
20.11.2024, 09:27
Помогаю со студенческими работами здесь

Syntax error unexpected $end and premature end-of-file единственный варнинг
Помогите исправить!! Device (FWH) { Name (_HID, EisaId (&quot;INT0800&quot;)) Method (_CRS, 0,...

Ведущие разработчики .NET (C#) Front-end и Back-end (Москва, не аутсорс)
В департамент разработки ПО крупной международной компании требуются: Lead Back-end developer: -Опыт разработки программного...

Error при создании .obj файла 85:End of file, no end directive
Добрый день! помогите разобраться с ошибкой! Компилирую следующий код в ibm personal computer macro assembler v 2.0: TITLE ...

With myChart With .Axes(xlCategory) .CategoryType = xlTimeScale .BaseUnit = xlseconds End With End With
MSDN утверждает: BaseUnit Property Applies To Axis object. Description Returns or sets the base unit for the specified category...

Работа в Германии (Front-End, Back-End или Full-Stack)
Ребят,я понимаю, реклама вас задолбала,но все-же, поступил заказ в наше агентство из Германии они ищут программиста.Работа в Германии,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и источниками (напряжения, ЭДС и тока). Найти токи и напряжения во всех элементах. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru