Страницы: 1 2 След.
RSS
Особенности работы редактора Visual BaSic при создании пользовательской функции
 
   Здравствуйте.
  Пытаюсь создать свою функцию, которая могла бы выводить результат какого-нибудь вычисления в виде "результат± погрешность" без лишних - не важных младших разрядов. Например 23,15± 0.02 вместо значение 23,15000236587 и погрешность 0,0235987. Столкнулся с проблемой, когда ещё при вводе исходных данных редактор САМ "пробегает " мой код и выводит сообщение, которое находится уже в самом коде функции. Причём это происходит даже если я ставлю точки останова - он на них не реагирует. Упрощённый пример привожу ниже. В нём, ещё при вводе буквы вместо погрешности, сразу же получаю сообщение: "Вместо числа введено непонятно что. Исправьте.", да ещё и не один раз. Дальше происходит совсем непонятное повторение этих же сообщений при моей реакции.
Код
Public Function Пример(ByVal варЗначение As Variant, ByVal варПогрешность As Variant, Optional ByVal стрПараметрВывода As String)
    Dim стрЗаголовок As String
    Dim стрСообщение As String
    Dim стрОтклик As String
    
    стрЗаголовок = "Функция Пример"
    стрСообщение = "Вместо числа введено непонятно что. Исправьте."
    If Not IsNumeric(варПогрешность) Then
        стрОтклик = MsgBox(стрСообщение, vbOKOnly, стрЗаголовок)
        End
    End If
End Function
 
Редактор САМ по функциям не бегает. Если только на предмет проверить, не написали ли вы чего-нибудь такого, что точно писать нельзя.
И функция сама по себе не функционирует.
Так что это не редактор САМ, и автор кода САМ наваял нечто.
 
Не совсем понял, что значит "не функционирует" - не запускается, что ли? Я её вызываю из книги, т.е. ввожу "=" нахожу в пользовательских и далее вставляю исходные данные.  
 
Цитата
chesas написал:
когда ещё при вводе исходных данных
Пока ячейка в режиме редактирования (вводятся данные), макросы не работают.
 
Какая ячейка? Я ввожу данные в окно для ввода исходных данных функции. Если та, где вводится функция, то это и есть мой вопрос - я ввожу данные и сразу же получаю сообщение, почему?
Изменено: chesas - 18.04.2019 18:10:35
 
Может какие-то настройки самого редактора?
 
chesas, MsgBox в функции - плохая практика. Вместо этого функция может возвращать значение ошибки, как это делают функции листа, например
Код
    If Not IsNumeric(варПогрешность) Then
      Пример = CVErr(xlErrValue) '#ЗНАЧ!
    End If
Использовать End в коде следует только в крайнем случае. Здесь он вообще не нужен.
 
Исправил на
Код
Public Function Пример1(ByVal варЗначение As Variant, ByVal варПогрешность As Variant, Optional ByVal стрПараметрВывода As String)
    Dim стрЗаголовок As String
    Dim стрСообщение As String
    Dim стрОтклик As String
    
    стрЗаголовок = "Функция Пример"
    стрСообщение = "Вместо числа введено непонятно что. Исправьте."
    If Not IsNumeric(варПогрешность) Then
      Пример = CVErr(xlErrValue) '#ЗНАЧ!
    End If
End Function
 
И при вызове функции получил сообщение, что у данной функции нет аргументов.
 
Цитата
chesas написал:
Создание пользовательской функции
Что должна делать функция? Вот это и должно быть понятно из названия темы. Предложите новое - модераторы поменяют.
 
   В самом первом сообщении я написал, что она должна делать. Вопрос больше касается моего непонимания отладки создания пользовательской функции - всё равно какой. До неё даже ещё не дошло дело.
Изменено: chesas - 18.04.2019 18:33:53
 
Цитата
chesas написал:
Вопрос больше касается моего непонимания отладки создания пользовательской функции - всё равно какой.
Тогда и переформулируйте в этом ключе.
 
   Может быть, особенности работы редактора Visual BaSic при создании пользовательской функции?
Изменено: chesas - 18.04.2019 18:40:46
 
Цитата
chesas написал:
при вызове функции получил сообщение, что у данной функции нет аргументов
Какой именно функции? В #1 функция объявлена как Пример, в #8 функция объявлена как Пример1 (а значение присваивается переменной Пример).
Приложите уже файл в соотв. с Правилами.
Изменено: Казанский - 18.04.2019 18:41:52
 
Прошу прощения. Должен ненадолго отлучиться.
 
   Ещё раз повторяю, что функция НЕ ВАЖНА, вопрос по работе самого редактора VB. Я не могу, понять почему редактор показывает моё же сообщение, но раньше чем я предполагал - ещё при вводе исходных данных. Такое впечатление, что по ходу ввода, он уже "пробегает" мой код и делает самостоятельно то, что я хотел бы сделать потом - по ходу выполнения функции.
  Ваш вариант хорош #7, но хотелось бы всё таки сообщение. А почему нежелательно использование MsgBox в функциях - то, что происходит с моим кодом это из-за него?
Цитата
Какой именно функции? В #1 функция объявлена как Пример, в #8 функция объявлена как Пример1 (а значение присваивается переменной Пример).
Приложите уже файл в соотв. с Правилами.
  Извиняюсь, конечно же ошибся - Пример1. И да - в этом случае ничего ненормального не происходит, но и нет сообщения...
Код
Public Function Пример1(ByVal варЗначение As Variant, ByVal варПогрешность As Variant, Optional ByVal стрПараметрВывода As String)
    Dim стрЗаголовок As String
    Dim стрСообщение As String
    Dim стрОтклик As String
    
    стрЗаголовок = "Функция Пример"
    стрСообщение = "Вместо числа введено непонятно что. Исправьте."
    If Not IsNumeric(варПогрешность) Then
      Пример1 = CVErr(xlErrValue) '#ЗНАЧ!
    End If
End Function
 
Все отрабатывает как и должно. Приложите файл пример, что вы хотите получить и что не получается.
«Бритва Оккама» или «Принцип Калашникова»?
 
Цитата
chesas написал:
что функция НЕ ВАЖНА, вопрос по работе самого редактора VB.
Странно задавать вопрос про редактор, а выкладывать не важную функцию, кто же знает что вы там в редакторе сделали, что вам сообщение показывают. У меня функция отрабатывает как нужно. Изначально функция равна Empty, если варПогрешность является числом, то функция возвращает Empty, иначе #ЗНАЧ. Для меня непонятно, какой вы хотите получить ответ.
Изменено: Nordheim - 19.04.2019 13:23:37
"Все гениальное просто, а все простое гениально!!!"
 
Смотрите мой код - #1, Вы видимо проверяете с исправлением от Казанского #7. Сейчас выложу всё по подробнее.
 
   Хочу создать функцию, которая могла бы выводить результат в виде "значение± погрешность" без лишних - не важных младших разрядов. Например 23,15± 0,02 по имеющимся исходным данным: значению - 23,15000236587 и погрешности - 0,0235987. В начале кода самой функции у меня есть проверка на правильность ввода исходных, чтобы не было потом недоразумений. И только после проверки - убедившись, что введённые два аргумента действительно числа(третий параметр нужен для вариации выводом) собрался писать саму обработку. Установил точку останова на первой строке кода, даже несколько точек. Столкнулся с тем, что если при вводе любого, одного из аргументов допущена ошибка, т.е. среди вводимого есть неподходящий символ - не цифра, не знак минус и не разделитель; то при нажатии "OK" выводится окно с предупреждением об ошибке, да ещё и неоднократно. Я не понимаю как и почему это происходит - ведь я только ввёл исходные данные и сразу же хочу остановить выполнение остановом. Упрощённый пример привожу ниже. В нём, при вводе первого символа - буквы в место ввода погрешности, получаю сообщение: "Введённое текст. Исправьте2.". Важно и то, что тип вводимых аргументов у меня Variant. И в чём тогда ошибка при вводе?
Код
Option Explicit
'1. Предусмотреть три варианта ввода: рукописный - с клавиатуры; вставка из буфера и указание ячейки Эксель.
'2. Однотипное поведение функции в каждом из этих трёх вариантов.
'3. При вводе не числа выдавать вразумительное сообщение непрерываясь.
'4. При перепутывании разделителя целой и дробной частей молча исправлять ошибку, также не прерываясь(возможны два варианта).
'5. При отсутствии в числе меньшем единицы впереди разделителя нуля, молча исправляет - добавляет перед разделителем ноль.

Public Function Округлить(ByVal варЗначение As Variant, ByVal варПогрешность As Variant, Optional ByVal стрПараметрВывода As String) As String
    Dim варВведённое As Variant
    Dim стрЧтоВведено As String
    
    варВведённое = варЗначение
    стрЧтоВведено = "Значение"
    Call ПроверкаПравильностиВвода(варВведённое, стрЧтоВведено)
    варВведённое = варПогрешность
    стрЧтоВведено = "Погрешность"
    Call ПроверкаПравильностиВвода(варВведённое, стрЧтоВведено)
    '...
    Округлить = " ± "
End Function

Private Sub ПроверкаПравильностиВвода(ByVal варВведённое As Variant, ByVal стрЧтоВведено As String)
    Dim стрТипВведённого As String
    Dim стрВведённое As String
    Dim цезПозицияТочки As Integer
    Dim стрВведённоеБезРазделителя As String
    Dim стрСообщение As String
    Dim целВсегоСимволовВоВведённом As Integer
    ' Пока написал лишь с предположением, что разделитель запятая - доработать и на точку! Недописано для ячейки!
    стрТипВведённого = TypeName(варВведённое) 'Первые четыре типа переменной варВведённое могут быть внесены вручную. _
                                                При вводе с таблицы, получаем тип - "Range".
    Select Case стрТипВведённого
    Case "String" 'Проверить, может перепутан лишь разделитель дробной части - вместо точки введена запятая.
        If InStr(стрВведённое, ".") <> 0 Then 'Определяем есть ли во введённом символ "точка" - "неправильный" разделитель целой и дробной частей.
            цезПозицияТочки = InStr(стрВведённое, ".") 'Определяем позицию разделителя.
            стрВведённоеБезРазделителя = Mid(стрВведённое, 1, цезПозицияТочки - 1) & Mid(стрВведённое, цезПозицияТочки + 1)
            If InStr(стрВведённоеБезРазделителя, ",") <> 0 Then 'Проверка на наличие второго разделителя.
                стрСообщение = "Во введённом - " & стрВведённое & ", как минимум, два разделителя: запятая и точка. Исправьте."
                MsgBox (стрСообщение)
            Else
                If IsNumeric(стрВведённоеБезРазделителя) Then 'Замена разделителя на правильный.
                    стрВведённое = Mid(стрВведённое, 1, цезПозицияТочки - 1) & "," & Mid(стрВведённое, цезПозицияТочки + 1)
                    варВведённое = CDbl(стрВведённое)
                 Else
                    стрСообщение = "Введённое - " & стрВведённое & " не число. Исправьте1."
                    MsgBox (стрСообщение)
                    End
                End If
            End If
         Else ' Во введённом нет точки.
            If Not (IsNumeric(стрВведённое)) Then
                стрСообщение = "Введённое - " & стрВведённое & " текст. Исправьте2."
                MsgBox (стрСообщение)
                End
            End If
        End If
    Case "Integer", "Long"
        ' Ничего не делаю.
    Case "Double"
    
    End Select
End Sub

 
Изменено: chesas - 19.04.2019 14:32:37
 
У Вас все вывернуто наизнанку. Обычно функция вызывается из процедуры, а не наоборот
Согласие есть продукт при полном непротивлении сторон
 
Мне-то нужна именно функция, с возможностью копирования по листу и по книгам... Конечно же можно и процедуру, но зачем создавать окна приглашения как минимум для ввода исходных данных, справки... если в функции это уже предусмотрено?
 
Да и дело принципа. Как ведёт себя редактор VB в вышеприведённом случае?
 
Цитата
chesas написал: Мне-то нужна именно функция, с возможностью копирования по листу и по книгам...
Вам придется копировать и все связанные с ней процедуры. какой в этом смысл?
Согласие есть продукт при полном непротивлении сторон
 
Зачем копировать, функция просто "лежит" во всегда открытой книге макросов и всегда доступна.
 
Цитата
chesas написал: Как ведёт себя редактор VB в вышеприведённом случае?
Нормально он себя ведет, т.е. никак
Согласие есть продукт при полном непротивлении сторон
 
Вы хотите сказать что если установить точку останова на строке "варВведённое = варЗначение" вызвать функцию, ввести исходные с ошибкой, то после нажатия "OK" код программы останавливается на вышеоговоренной строчке?
Изменено: chesas - 19.04.2019 16:05:15
 
Ничего я не хочу говорить кроме того, что Вы, воля ваша, какую-то ерунду пытаетесь изобразить
Согласие есть продукт при полном непротивлении сторон
 
Всё верно - только тут мы оказываемся после непонятно сколько раз появившихся окон с ошибкой!
 
Так вот ПОЧЕМУ ОНИ ПОЯВЛЯЮТСЯ? Или у меня какие-то настройки не те?
Страницы: 1 2 След.
Наверх