Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Клуб профессиональных программистов :: Выпуск #117


Клуб профессиональных программистов «Весельчак У»
Информационная рассылка сайта и форума.  Выпуск 117.  6 августа 2011 г.

Здравствуйте, уважаемые читатели!

Сегодня предлагаем вам еще две части статьи «Модульное тестирование ПО встроенных систем в среде Unity»: часть 2 и финальная часть 3.

Также предлагаем подборку тем нашего форума.




Пополнение «Книжной полки разработчика систем со встроенными микропроцессорами»:





Приятного чтения!




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

При написании подобных статей перед автором всегда стоит трудный выбор: какие примеры выбрать для иллюстрирования изложенного материала? Если выбрать чересчур примитивный пример, он будет слишком далек от реальности (никто еще не стал экспертом в программировании, проштудировав программу «Hello World»); если же взять пример из реальной жизни, он наверняка будет изобиловать лишними деталями, которые отвлекают от сути.

Как компромисс в качестве примера я позаимствую небольшой модуль для вычисления площади треугольника из своей предыдущей статьи, посвященной обработке исключений на C. Он несложен, и в то же время, помимо общих ошибок времени выполнения программы, в нем могут возникнуть специфические именно для данного приложения ошибки, наличие которых мы и попытаемся выловить при помощи модульных тестов.

Итак, приступаем.


Подготовка


Запасаемся инструментами


Как упоминалось ранее, теоретически автоматизированное тестирование можно было бы проводить и без инструментов, писать весь необходимый код вручную; однако использование готовых инструментов позволит нам сэкономить массу сил и времени. Поэтому мы отправимся на домашнюю страницу страницу Unity  и скачаем оттуда свежую версию. Продукт этот бесплатен.

В состав Unity, помимо библиотек исходных на C, входит набор скриптов для автоматизации некоторых действий. Эти скрипты написаны на языке Ruby. Язык этот интерпретируемый, и, следовательно, для их выполнения необходим интерпретатор Ruby. Скачать его можно здесь. Этот продукт также относится к бесплатным. После скачивания его следует инсталлировать в своей системе.

Если вы еще не знакомы с Ruby – не беда, для работы с готовыми скриптами это не потребуется. Для выполнения скрипта file.rb достаточно лишь набрать в командной строке

...


Полностью прочитать статью можно на нашем сайте, в разделе «Инструменты и технологии проектирования ПО».

Рефакторим тесты


Итак, мы с огорчением обнаружили, что наш код издает весьма отчетливо различимый душок дублирующегося кода. Напрашивается рефакторинг «выделение метода», которым мы сейчас и займемся. Поскольку данная тема не о рефакторинге и я еще ничего не рассказывал об инструментах для его проведения, проделаем его вручную, благо это не так уж сложно.

Анализ повторяющегося кода подсказывает нам, что имеет смысл выделить вспомогательную функцию, которая вызывает наш модуль с некоторыми параметрами и возвращает результат проверки. Тогда наш тест мог бы ограничиться лишь анализом этого результата.

Итак, находим повторяющийся код и выносим его в отдельную вспомогательную функцию:


Код: (C)
static void callTriangleAreaAndCheckException(double a, double b, double c)
{
    CEXCEPTION_T e;
    Try
    {
        triangleArea(a, b, c);
        TEST_FAIL_MESSAGE("No exception was thrown");
    }
    Catch(e)
    {
        TEST_ASSERT_EQUAL_UINT((unsigned int)NEGATIVE_SIDE, (unsigned int)e);
    }
}

Вспомогательная функция callTriangleAreaAndCheckException() вызывает нашу тестируемую функцию с заданными параметрами, перехватывает исключение, выбрасываемое ей во время работы, и сравнивает код этого исключения с ожидаемым. Если исключение не было выброшено, тест завершается по ошибке с выдачей соответствующего сообщения.

При использовании callTriangleAreaAndCheckException() наши два теста становятся до неприличия простыми:


Код: (C)
void test_Side_1_isLessThan_0_Exception(void)
{
    callTriangleAreaAndCheckException(-3.0, 4.0, 5.0);
}

void test_Side_2_isLessThan_0_Exception(void)
{
    callTriangleAreaAndCheckException(3.0, -4.0, 5.0);
}

Убедимся, что они по-прежнему работоспособны, несмотря на эту простоту:

...


Полностью прочитать статью можно на нашем сайте, в разделе «Инструменты и технологии проектирования ПО».

  • Программирование :: Неотложка
  • Ребята, помогите с написанием блок-схемы!!!! Если изначально задан только текст. Как быть?

    Добавлено через 3 минуты и 59 секунд:
    просто я никогда не сталкивалась с написанием блок-схем по инструкции
  • Здравствуйте! Второй день бьюсь над какой-то по сути смешной и простецкой вещью. Но, однако, не нашёл пока решения.

    Что хотелось получить:

    Приложение с тулбаром, на котором залипающая (как пауза в плеере) кнопка
    Причём, залипать и отлипать она должна по команде (в обработчике определённого события)

    Что я сделал уже:

    Я сделал приложение, тулбар, кнопки, конкретную кнопку, которая должна залипать. Присвоил ей стиль
    Код:
    m_wndToolBar.SetButtonStyle(12,TBBS_CHECKBOX); 

    - всё хорошо, индекс 12 - правильный, проверял. Т.е. она залипает и отлипает. Повесил обработчик события. Всё работает. НО - не могу командой заставить её залипнуть или отлипнуть. Пробовал так:
    Код:
    m_wndToolBar.GetToolBarCtrl().CheckButton(12,TRUE);
    - возвращает 0 - т.е. неуспех. Пытался проверить GetLastError - там ОК стоит.

    Пробовал так:
    Код:
    m_wndToolBar.GetToolBarCtrl().SetState(12,TBSTATE_CHECKED);
    - тоже самое

    И так:
    Код:
    m_wndToolBar.GetToolBarCtrl().PressButton(12,TRUE);

    - вызываю их все в тот момент, когда тулбар заведомо создан и существует. Эти команды повесил на событие выбора одного из пунктов меню.

    Почему не получается, как вы думаете? Буду очень признателен. Перерыл много чего, делал как в примерах. Всё равно не получается

    P.S. вызываю всё в событиях MainFrame так что область видимости вроде одна...
  • Программирование :: Общий :: Алгоритмы и математические задачи.
  • На хабре вышла статья - возможно, заинтересует кого-то у нас. Тут много было похожих обсуждений.

    http://habrahabr.ru/blogs/algorithm/125356/

    Алгоритм определения попадания точки в контур на основе комплексного анализа
  • Программирование :: С/С++
  • Собственно, сабж. Имеется комплект файлов и хидеров, а также makefile:

    Код:
    CC      = gcc
    #PROF    = -p
    NOCRYPT =

    # Uncomment the two lines below if compiling on a Solaris box
    #SOLARIS_FLAG = -Dsun -DSYSV
    #SOLARIS_LINK = -lnsl -lsocket

    #Uncomment the line below if you are getting a line like:
    #interp.c:757: warning: int format, time_t arg (arg 7)
    #TIME = -DTIMEFORMAT

    #Uncomment the line below if you are getting implicit decleration of re_exec
    #REG = -DREGEX

    #Uncomment the line below if you are getting undefined re_exec errors
    #NEED_REG = -lgnuregex

    #Uncomment the line below if you are getting undefined crypt errors
    #NEED_CRYPT = -lcrypt

    #DBUGFLG = -DREQUESTS

    #Uncomment the line below if you want a performance increase though beware
    #your core files may not be as much of a benefit if you do.
    #OPT_FLAG = -finline-functions -funroll-loops -fdefer-pop -fstrength-reduce

    C_FLAGS = $(OPT_FLAG) -O -g3 -Wall -Wuninitialized $(PROF) $(NOCRYPT) $(DBUGFLG) -DSMAUG $(SOLARIS_FLAG) $(TIME) $(REG)
    L_FLAGS = $(OPT_FLAG) $(PROF) $(SOLARIS_LINK) $(NEED_CRYPT)

    #Uncomment the next three comments below if you want to use IMC
    #USE_IMC    = -DUSE_IMC

    #IMC_OFILES = imc.o imc-mail.o imc-interp.o imc-util.o imc-config.o \
    #        imc-events.o imc-version.o imc-mercbase.o ice.o icec.o icec-mercbase.o

    #IMC_CFILES = imc.c imc-mail.c imc-interp.c imc-util.c imc-config.c \
    #        imc-events.c imc-version.c imc-mercbase.c ice.c icec.c icec-mercbase.c

    O_FILES = act_comm.o act_info.o act_move.o act_obj.o act_wiz.o boards.o \
              build.o clans.o comm.o comments.o const.o db.o deity.o fight.o \
              handler.o hashstr.o ibuild.o ident.o interp.o magic.o makeobjs.o \
              mapout.o misc.o mpxset.o mud_comm.o mud_prog.o player.o polymorph.o \
              requests.o reset.o save.o shops.o skills.o special.o tables.o \
              track.o update.o grub.o stat_obj.o ban.o services.o planes.o \
              imm_host.o $(IMC_OFILES) colorize.o

    C_FILES = act_comm.c act_info.c act_move.c act_obj.c act_wiz.c boards.c \
              build.c clans.c comm.c comments.c const.c db.c deity.c fight.c \
              handler.c hashstr.c ibuild.c ident.c interp.c magic.c makeobjs.c \
              mapout.c misc.c mpxset.c mud_comm.c mud_prog.c player.c polymorph.c \
              requests.c reset.c save.c shops.c skills.c special.c tables.c \
              track.c update.c grub.c stat_obj.c ban.c services.c planes.c \
              imm_host.c $(IMC_CFILES) colorize.c

    H_FILES = mud.h bet.h imc-config.h imc-mercbase.h imc-mercdefs.h imc.h \
              ice.h icec.h icec-mercbase.h

    all:
    make smaug

    smaug: $(O_FILES)
    rm -f smaug
    $(CC) $(L_FLAGS) $(USE_IMC) -o smaug $(O_FILES)
    chmod g+w smaug
    chmod a+x smaug
    chmod g+w $(O_FILES)

    .c.o: mud.h
    $(CC) -c $(C_FLAGS) $(USE_IMC) $<

    clean:
    rm -f *.o smaug *~

    поставил MinGW, после ряда танцев с бубном он стал выдавать:

    Код:
    C:\dev\projects\arda\Vetka\dist\src>mingw32-make
    make smaug
    MAKE Version 5.2  Copyright (c) 1987, 1998 Inprise Corp.
    Fatal: 'act_comm.o' does not exist - don't know how to make it
    mingw32-make: *** [all] Error 1

    я его понимаю - либы с расширением *.о генерит линуксовый gcc. Возможно ли как-то собрать проект под виндой?
  • Ребята, доброго времени суток, я к вам за советом  :shuffle:
    Честно говоря, не знала как бы поточнее назвать тему...

    Пытаюсь реализовать вот такую штуку (на самом деле проект не маленький, но с выделением-освобождением памяти не могу разобраться, поэтому сделала упрощенную модель):

    Код: (C++)
    #include <stdio.h>
    #include <iostream.h>

    //есть некоторый собственный класс

    class Some
    {
    public:
        Some() { cout << "I am Some object " << endl; }
        ~Some() { cout << "I was delete " << endl ;  }

        void printSomeNumber() { cout << some_number; }
        void setSomeNumber(int temp) { some_number = temp; }
        
    private:
       int some_number;
    };

    //в данной функции выделяется память для указателя на объект вышеописанного класса -
    //первый параметр, сколько будет выделено память сохраняется во второй параметр
    //далее в этот массив что-то сохранияется

    void getObjectIdentificators(Some **oids, int &oid_count)
    {
       *oids = new Some[4];
       oid_count = 5;
      
       for (int i = 0; i < 4; i++)
       {
          oids[i]->setSomeNumber(i);
       }
    }

    // главная функция программы в которой инициализируется указатель
    // и удаляется, после того, как функция отработает

    int main()
    {

    Some *oids = NULL;

    int oid_count;

    getObjectIdentificators (&oids, oid_count);

    for (int i = 0; i < oid_count; i++)
    {
       oids[i].printSomeNumber();
    }

    delete[] oids;

    return 1;
    }

    Вопрос в чем, как правильно выделить память, чтобы она выделилась не для локального указателя и указатель все еще продолжал на нее указывать, после выхода из функции getObjectIdentificators?  :-/



    Добавлено через 2 минуты и 33 секунды:
    на данный момент, при выходе из функции getObjectIdentificators и попытке обратиться к oids происходит "Segmentation fault"
  • Программирование :: С/С++ :: ANSI С/С++
  • Да, иногда начинаю сомневаться, что хорошо знаю C.

    В доке к микроконтроллеру дан пример:

    Код: (c,1,1,3,17)
    unsigned int USART_Receive( void )
    {
        unsigned char status, resh, resl;
    /* Wait for data to be received */
        while ( !(UCSRnA & (1<<RXCn)) )
        ;
    /* Get status and 9th bit, then data */
    /* from buffer */
        status = UCSRnA;
        resh = UCSRnB;
        resl = UDRn;
    /* If error, return -1 */
        if ( status & (1<<FEn)|(1<<DORn)|(1<<UPEn) )
            return -1;
    /* Filter the 9th bit, then return */
        resh = (resh >> 1) & 0x01;
        return ((resh << 8) | resl);
    }

    Интересует 17-ая строчка кода. Строку 1 и 3 я пометил, чтобы было видно типы переменных и возвращаемого значения.

    В операторе return стоит выражение в скобках. В выражении участвуют только переменные типа unsigned char. У меня вызвал сомнение сдвиг на 8: разве он приводит к автоматическому расширению типа до unsigned short или unsigned int?

    Либо я что-то не знаю, либо в примере ошибка.
  • Программирование :: С/С++ :: WinAPI & Visual C++
  • Может кто помнит, я задавал кучу вопросов, когда делал программу для удалённого администрирования. Так вот, поделка сия готова, и заказчик задал вопрос - как это чудо познакомить с одинэской, то есть чтобы программу можно было запустить из 1C-ного кода, а также управлять запущенной программой оттуда (управлять - максимум вызывать определённые функции).

    Как это делается ? О_о
  •  вопрос. Имелся в солюшене проект с диалогом и другими ресурсами (в частности с курсорами). Добавил я проект для DLL , на все нужные хедеры завёл ссылки в дерево . А на ресурсы то не сошлёшься, пришлось копировать дерево ресурсов. Всё бы и ничего, но ведь легко забыть снова сделать копию, когда в том проекте я что-то подправлю. Как-то это решается более удобно ?
  • Программирование :: Delphi
  • Делая двойной щелчок в клиентской зоне я проверял какие приходят Message.Msg и получалось что одно WM_LBUTTONDOWN и два WM_LBUTTONUP. Почему?
    Код:
    implementation

    {$R *.dfm}

    var countClick :Word;
        Description: Word;

    procedure TForm1.Wndproc(var Message: TMessage);
    begin

      case Message.Msg of

        WM_LBUTTONDOWN, WM_LBUTTONUP:
        begin
          countClick := countClick + 1;

          Description := Message.Msg;

        end;

      else
        inherited;
      end;

    end;
  • Программирование :: VisualBasic
  • Понадобилось мне сделать переключалку языков на Visual Basic 6. Поискал по Интернету, везде один и тот же вариант:
    Код:
    Private Declare Function ActivateKeyboardLayout Lib "user32" (ByVal HKL As Long, ByVal flags As Long) As Long 

    ' Переключаем на русский
    Call ActivateKeyboardLayout(68748313, 0)
    ' Переключаем на английский
    Call ActivateKeyboardLayout(67699721, 0)
    Или варианты той же программы, например, отсутствует слово Private, или числа вынесены в отдельные константы. Но это неважно.
    И главное, на форумах все говорят: Спасибо, всё прекрасно работает!
    А у меня, как ни ввожу, на оператор Declare выдает вот такую ошибку:
    Only comments may appear after End Sub, End Function, or End Property

    Причем независимо от того, куда я эту строку ставлю - в начале программы, где определения Dim и Const или в середину, прямо там, где мне нужно переключать раскладку, в том модуле, в котором я ее переключаю, или в модуле Form_Load, или в любом другом.

    А если этот оператор поставить в область (Declarations), где ему, казалось бы, самое место, то получаю вот такую ошибку:
    Constants, fixed-length strings, arrays, user-defined types and Declare statements not allowed as Public members of object modules

    Вопрос: Как заставить этот код работать? Может, надо ещё какие-то действия произвести?
    А может быть, нужно просто скопировать этот файл user32.dll из каталога Windows\System32 в каталог моего проекта?
    Что скажете?

    Спрашивал на другом форуме, там тоже все говорят, что нормально работает.
    Неужели у меня одного эта ошибка вылезает? В чем дело может быть?
  • Программирование :: VisualBasic :: Visual Basic for Applications
  • Здравствуйте.
    Как программно узнать изменен документ  Ms Word или нет? Как установить признак модифицированности документа?
  • Программирование :: Java
  • по уверениям разработчика, достаточно заменить в батнике для компиляции путь к jdk и все будет замечательно. батник выглядит так:

    Код:
    REM Make sure you are building with java v1.6 or higher
    REM SET Java_Home="C:\Program Files\Java\jdk1.6.0_24"
    set CLASSPATH=.;%Java_Home%\lib\dt.jar;%Java_Home%\lib\tools.jar;.\lib\js.jar;.\lib\jzlib.jar
    SET JAVACPATH=%Java_Home%\bin\javac -g -nowarn -deprecation

    IF "%1" == "docs" GOTO :DOCS

    %JAVACPATH% com/planet_ink/fakedb/*.java
    %JAVACPATH% com/planet_ink/coffee_mud/Abilities/*.java
    ...

    пусть к своему JDK я поменял. в итоге при компиляции выдается куча ошибок, типа "Системе не удается найти указанный файл". хотя сам javac у меня прописан, т.е. он в любом каталоге вызывается и нормально отрабатывает.

    в чем могут быть грабли?
  • Программирование :: Программирование 1С
  • Вот какая-то проблема - жена мучается, не может установить HASP для 1С и ЭОН , она искала, как это сделать, что только не пробовала, говорит, ну никак - что-то сидит в системе и не даёт поставить (раньше вся эта фигня вроде работала, а потом обновления были)

    Так вот - как этот HASP вообще начисто из системы вымести ?
  • Программирование :: Программирование 1С :: 1С 7.x
  • Здравствуйте уважаемые форумчане! в панорамировании пока новичок, возникла такая ситуация - есть рабочее место с 1с предприятие 7.7 Штрих-М кассир, все настроено все работает нормально, но нужно что бы кассир мог делать "СТОРНО" для товара до определенной цены (например товар с ценной до 100 руб. можно отменить - сторно)
    Подскажите пожалуйста какие нибудь идеи.
    модуль сторно могу выложить
    Код:
    Процедура Сторно()
            Если НовыйЧек=1 Тогда
                НовыйЧек();
            КонецЕсли;
           
            Если НачинатьСНуля=1 Тогда
                НачалоСНуля();
            КонецЕсли;
           
            Если ЧекОткрыт=0 Тогда
                Возврат;
            КонецЕсли;
           
            Если ВидЧека>3 Тогда
                Сигнал();
                Возврат;
            КонецЕсли;
            ВнешняяКомпонента.MaxKeyNum=-1;
            ВнешняяКомпонента.MinKeyNum=-1;
           
            Если Чек.КоличествоСтрок()>0 Тогда
                Если Чек.Флаг=2 Тогда
                    ВнешняяКомпонента.MaxKeyNum=255;
                    ВнешняяКомпонента.MinKeyNum=1;
                    Возврат;
                КонецЕсли;
                Цифры=?(ДесТ=2,"0.00","0.");
                ПоложениеТочки=ДесТ;
                НажатаТочка=0;
                Кол=1;
                НажатПромИтог=0;
                ТекТовар=0;
                К=1;
               
                Если ПустоеЗначение(Чек.Товар)=0 Тогда
                    ТекТовар=?(Чек.Товар.Вид()="Товары",Чек.Товар,Чек.Товар.Владелец);
                   
                    Если Чек.Товар.Вид()="Единицы" Тогда
                        К=?(Чек.Товар.Коэффициент=0,1,Чек.Товар.Коэффициент);
                    КонецЕсли;
                КонецЕсли;
               
                Если ПроверкаПрав("Сторно")=0 Тогда
                    СтрокаДляТовараКК(3,0,ТекТовар,Чек.Количество*К,Чек.Цена/К,Чек.Сумма,,Чек.НомерСтроки,2006,Чек.СуммаСкидки);
                    ВнешняяКомпонента.MaxKeyNum=255;
                    ВнешняяКомпонента.MinKeyNum=1;
                    Возврат;
                КонецЕсли;
               
                Если (ИтогЧека("СуммаСоСкидкой")-СуммаСкидкиНаЧек-Чек.СуммаСоСкидкой<0) И (СкидкаНаЧек=0) И (ЕстьВозвратыВЧекеПродажи=0) Тогда
                    ЗвуковойСигнал();
                    ВывестиПредупреждение("Полученная сумма будет меньше нуля!","Сторно невозможно!");
                    ВнешняяКомпонента.MaxKeyNum=255;
                    ВнешняяКомпонента.MinKeyNum=1;
                    Возврат;
                КонецЕсли;
               
                Если ВидЧека<>3 Тогда
                    Если ПечататьКаждуюСтроку>0 Тогда
                        Если ПечатьРегистрации(Чек.Номер,Чек.Товар,Чек.Количество,Чек.Цена,Чек.Секция,Чек.Продавец,1)=0 Тогда
                            ВнешняяКомпонента.MaxKeyNum=255;
                            ВнешняяКомпонента.MinKeyNum=1;
                            Возврат;
                        КонецЕсли;
                       
                        Если Чек.СуммаСкидки<>0 Тогда
                            СтрокаДляПечати="";
                           
                            Если ПустоеЗначение(Чек.АвтоматическаяСкидка)=0 Тогда
                                СтрокаДляПечати=СокрЛП­(Чек.АвтоматическаяСкидка.ТекстДляЧека);
                            КонецЕсли;
                           
                            Если ПустоеЗначение(Чек.ФиксированнаяСкидка)=0 Тогда
                                СтрокаДляПечати=СокрЛП­(Чек.ФиксированнаяСкидка.ТекстДляЧека);
                            КонецЕсли;
                           
                            Если ПечатьСкидки(Чек.СуммаСкидки,Чек.Скидка,Чек.СуммаСоСкидкой,СтрокаДляПечати)=0 Тогда
                                ВнешняяКомпонента.MaxKeyNum=255;
                                ВнешняяКомпонента.MinKeyNum=1;
                                Возврат;
                            КонецЕсли;
                        КонецЕсли;
                    КонецЕсли;
                    Транз=СоздатьОбъект("Справочник.ВремТранзакции");
                    Знак=?(ВидЧека=1,-1,1);
                   
                    Если Чек.Флаг=3 Тогда
                        Знак=1;
                    КонецЕсли;
                    Транз.Новый();
                    Транз.Код=Формат(Число(Чек.ТранзакцияРегистрации)+7,"Ч(0)7");
                    Транз.Наименование=?(ПустоеЗначение(Чек.Товар)=0,"Сторно","Секция");
                    Транз.НомерККМ=Константа.НомерПОС;
                    Транз.ДатаТранз=ТекущаяДата();
                    Транз.ВремяТранз=ТекущееВремя();
                    Транз.ТипТранзакции=?(ПустоеЗначение(Чек.Товар)=0,12,2);
                    Транз.НомерЧека=НомерЧека;
                    Транз.Секция=Чек.Секция;
                    Транз.КодКассира=ТекущийПользователь.Код;
                    Транз.КодТовара=?(ПустоеЗначение(Чек.Товар)=0,ТекТовар.Код,0);
                    Транз.Цена=Чек.Цена/К;
                    Транз.Количество=Знак*Чек.Количество*К;
                    Транз.Сумма=Окр(Знак*Чек.СуммаСоСкидкой,ДесТ);
                    Попытка   Транз.Записать();
                    Исключение     ЗвуковойСигнал();
                        ВывестиПредупреждение("Ошибка работы с базой данных:"+РазделительСтрок+ОписаниеОшибки()+"!","Ошибка базы!");
                        ВнешняяКомпонента.MaxKeyNum=255;
                        ВнешняяКомпонента.MinKeyNum=1;
                        Возврат;
                    КонецПопытки;
                    Чек.Флаг=2;
                    СтрокаДляТовараКК(0,0,ТекТовар,Чек.Количество*К,Чек.Цена/К,Чек.Сумма,,Чек.НомерСтроки,2006,Чек.СуммаСкидки);
                    ПозЧ=РасчСкидкиНаПоз.НайтиЗначение(Чек.НомерСтроки);
                   
                    Если ПозЧ>0 Тогда
                        РасчСкидкиНаПоз.УдалитьЗначение(ПозЧ);
                    КонецЕсли;
                   
                    Если СкидкаНаЧек<>0 Тогда
                        Если ПересчетСкидкиНаЧек()=0 Тогда
                            ВнешняяКомпонента.MaxKeyNum=255;
                            ВнешняяКомпонента.MinKeyNum=1;
                            Возврат;
                        КонецЕсли;
                    КонецЕсли;
                Иначе   Чек.УдалитьСтроку();
                КонецЕсли;
            КонецЕсли;
           
            Если (Константа.РазрешитьАвтоматическиеСкидки>0) И (ВидЧека=1) Тогда
                РассчитатьАвтоматическуюСкидкуНаЧек();
            КонецЕсли;
           
            Если (Константа.РазрешитьНакопительныеСкидки>0)     И (ПустоеЗначение(ВыбраннаяДисконтнаяКарта)=0) Тогда
                Если (ПолучитьСкидкуПоДисконтнойКарте(ВыбраннаяДисконтнаяКарта)<>ДисконтнаяСкидкаНаЧек) ИЛИ (Константа.КонтрольСкидок>0) Тогда
                    Скидка(0,1,,1,,ВыбраннаяДисконтнаяКарта,1);
                    Скидка(0,0,,1,,ВыбраннаяДисконтнаяКарта,1);
                КонецЕсли;
            КонецЕсли;
           
            Если (ПустоеЗначение(ФиксированнаяСкидкаНаЧек)=0) И (Константа.КонтрольСкидок>0) Тогда
               
                Если ФиксированнаяСкидкаНаЧек.ВидСкидки=Перечисление.ВидыСкидок.Процентная Тогда
                    Скидка(?(ФиксированнаяСкидкаНаЧек.ТипСкидки=Перечисление.ТипыСкидок.Скидка,0,2),1,,1,ФиксированнаяСкидкаНаЧек);
                    Скидка(?(ФиксированнаяСкидкаНаЧек.ТипСкидки=Перечисление.ТипыСкидок.Скидка,0,2),,,1,ФиксированнаяСкидкаНаЧек);
                КонецЕсли;
            КонецЕсли;
            ПересчетСкидкиНаЧек();
           
            Если ВидЧека=1 Тогда
                Операция="Продажа";
            ИначеЕсли ВидЧека=2 Тогда
                Если ФлагВозврата=1 Тогда
                    Операция="Возврат";
                Иначе   Операция="Аннул.";
                КонецЕсли;
            ИначеЕсли ВидЧека=3 Тогда
                Если ФлагВозврата=1 Тогда
                    Операция="Возврат по №";
                Иначе   Операция="Аннул. по №";
                КонецЕсли;
            КонецЕсли;
           
            Если Константа.РаботаСДисплеем>0 Тогда
               
                Если Константа.РазделятьТриады=0 Тогда
                    ФорматСумм="Ч."+ДесТ;
                Иначе   ФорматСумм="Ч."+ДесТ+".'";
                КонецЕсли;
               
                Если Константа.ВыводитьПромИтогНаДисплей>0 Тогда
                    ВывестиСтрокуНаДисплей("Сторно "+ФормС(Чек.СуммаСоСкидкой,ФорматСумм),1);
                    ВывестиСтрокуНаДисплей("Пром.итог "+ФормС(ИтогЧека("СуммаСоСкидкой")-СуммаСкидкиНаЧек,ФорматСумм),2);
                Иначе   ВывестиСтрокуНаДисплей("Сторно",1);
                    ВывестиСтрокуНаДисплей(ФормС(Чек.СуммаСоСкидкой,ФорматСумм),2);
                КонецЕсли;
            КонецЕсли;
            ОбновитьНомераСтрок();
            ВнешняяКомпонента.MaxKeyNum=255;
            ВнешняяКомпонента.MinKeyNum=1;
        КонецПроцедуры
  • Делаю Отчет(((нужна помощь квалифицированных специалистов..))

    Дело в том,  что обычно я что-то исправляла в конфигурации, а теперь мне нужно сделать свой отчет, но так как я это делаю впервые, то у меня возникли вопросы, которые спросить просто не у кого.
    Очень надеюсь на Вашу помощь…

    Хочу посчитать из журнала актов количество строк, которые начитаются с ООО, МУП, МУ и МП  в столбце Лицо.

    Пишет вот такую ошибку:

    Код:
    Если Сред(Д4.Лицо,1,4)="ООО " или Сред(Д4.Лицо,1,4)<<?>>="МУП " 
    {Отчет.222.Форма.Модуль(31)}: Неправильное использование арифметической или строковой операции

    Вот кусочек отчета:

    Код:
        Д4 = СоздатьОбъект("Документ.Акт");
        А1 = 0; А10 = 0; А5 = 0;
        Д4.ВыбратьДокументы(Д1,Д2);
         Пока Д4.ПолучитьДокумент()>0 Цикл
             А10 = А10 + 1;          
             Если Сред(Д4.Лицо,1,4)="ООО " или Сред(Д4.Лицо,1,4)="МУП "
                или Сред(Д4.Лицо,1,3)="МУ "   или Сред(Д4.Лицо,1,3)="МП " Тогда
                А1 = А1 + 1;
             Иначе А5=А5+1;
             КонецЕсли;      
         КонецЦикла;

    Скажите в чем моя ошибка? (((

    Добавлено через 3 часа, 31 минуту и 43 секунды:
    Спасибо за ответ..)))
    теперь уже другой ..))
    ошибка A1<<?>>
     Переменная не определена (A1)
    Как ее еще нужно определить... Выводиться она у меня в таблице(свойство ячейки выражение в ней стоит A1, A3.... )
  • Программирование :: Программирование 1С :: 1С 8.x
  • Еще раз здравствуйте)

    Ваяю еще одну печатную форму для документа "Реализация товоров и услуг"
    В типовой там в табличной части выводится только Количество, Цена и Сумма. Мне нужно, чтобы еще в каждой строке выводился НДС и сумма с учетом НДС.

    В общем поковырял код, макет нарисовал. проверяю - все отлично выводится. и текстовки и сведения об организации. а вот табличная часть остается пустой. почему - не понимаю. прикладываю внешнюю обработку к сообщению(там 2 макета. Акт1 - исходный, Акт- сделанный мной), буду премного благодарен если ткнете в ошибку носом)

    Добавлено через 1 час, 16 минут и 17 секунд:
    меня смущает вот этот код

    Код:
    Если Проведен И (Шапка.РасчетыВУсловныхЕдиницах
    ИЛИ (Шапка.ВалютаДокумента <> мВалютаРегламентированногоУчета И ТаблицаУслуги.Дата >= '20090101000000')) Тогда

    Запрос = Новый Запрос;
    Запрос.УстановитьПараметр("Ссылка", Ссылка);
    Запрос.УстановитьПараметр("СчетУчетаРасчетовСКонтрагентом", СчетУчетаРасчетовСКонтрагентом);
    Текст =
    во внешней обработке он ругается на  то, что непонятно что за проведен, ссылка и СчетУчета.

    я так понимаю нужно видоизменить так

    Код:
    Если СсылкаНаОбъект.Проведен И (Шапка.РасчетыВУсловныхЕдиницах
    ИЛИ (Шапка.ВалютаДокумента <> мВалютаРегламентированногоУчета И ТаблицаУслуги.Дата >= '20090101000000')) Тогда

    Запрос = Новый Запрос;
    Запрос.УстановитьПараметр("Ссылка", СсылкаНаОбъект);
    Запрос.УстановитьПараметр("СчетУчетаРасчетовСКонтрагентом", СсылкаНаОбъект.СчетУчетаРасчетовСКонтрагентом);
    Текст =

    или я дурак и все не так?
  • Добрый день.
    Делал внешнюю печатную форму для документа ОказаниеУслуг.

    Если правил в самом модуле документа - все работало. Стал переносить во внешнюю обработку, но при попытке ее запустить вылетает ошибка: Значение не является значением объектного типа (ПараметрыПрописиНаРусском)
    Вот код, косяка не вижу. Выручайте.
    Код:
    Перем мВалютаРегламентированногоУчета Экспорт;
    Функция Печать() Экспорт

    Запрос = Новый Запрос;
    Запрос.УстановитьПараметр("ТекущийДокумент", СсылкаНаОбъект);
        Запрос.Текст =
    "ВЫБРАТЬ
    | ОказаниеУслуг.Ссылка.Номер,
    | ОказаниеУслуг.Ссылка.Дата,
    | ОказаниеУслуг.Ссылка.Организация,
    | ОказаниеУслуг.Ссылка.Организация КАК Поставщик,
    | ОказаниеУслуг.Ссылка.УчитыватьНДС,
    | ОказаниеУслуг.Ссылка.СуммаВключаетНДС,
    | ОказаниеУслуг.Ссылка.СтавкаНДС,
    | ОказаниеУслуг.Ссылка.Номенклатура,
        |   ОказаниеУслуг.Ссылка.ВидВзаиморасчетов,
    |   ОказаниеУслуг.Ссылка.Исполнитель,
    |   ОказаниеУслуг.Ссылка.Заказчик,
    | ВЫБОР
    | КОГДА (НЕ ОказаниеУслуг.Ссылка.Номенклатура.НаименованиеПолное ПОДОБНО """")
    | ТОГДА ВЫРАЗИТЬ(ОказаниеУслуг.Ссылка.Номенклатура.НаименованиеПолное КАК СТРОКА(1000))
    | ИНАЧЕ ОказаниеУслуг.Ссылка.Номенклатура.Наименование
    | КОНЕЦ КАК Товар,
    | ОказаниеУслуг.Количество КАК Количество,
    | ОказаниеУслуг.Ссылка.Номенклатура.БазоваяЕдиницаИзмерения КАК ЕдиницаИзмерения,
    | ОказаниеУслуг.НомерСтроки КАК НомерСтроки,
    | ОказаниеУслуг.Контрагент КАК Получатель,
    | ОказаниеУслуг.ДоговорКонтрагента,
    | ОказаниеУслуг.Цена КАК Цена,
    | ОказаниеУслуг.Сумма,
    | ОказаниеУслуг.СуммаНДС
    |ИЗ
    | Документ.ОказаниеУслуг.Контрагенты КАК ОказаниеУслуг
    |ГДЕ
    | ОказаниеУслуг.Ссылка = &ТекущийДокумент
    | И ОказаниеУслуг.Сумма > 0
    |
    |УПОРЯДОЧИТЬ ПО
    | НомерСтроки";
    Выборка = Запрос.Выполнить().Выбрать();

    ТабДокумент = Новый ТабличныйДокумент;
    ТабДокумент.ИмяПараметровПечати = "ПАРАМЕТРЫ_ПЕЧАТИ_ОказаниеУслуг_Акты";

    Пока Выборка.Следующий() Цикл

    Макет = ПолучитьМакет("Акт");
    ОбластьМакета = Макет.ПолучитьОбласть("Акт");

    // Вывод полного названия организации и ее адреса.
    СведенияОбОрганизации   = УправлениеКонтактнойИнформацией.СведенияОЮрФизЛице(Выборка.Организация, Выборка.Дата);
    ПредставлениеПоставщика = ФормированиеПечатныхФорм.ОписаниеОрганизации(СведенияОбОрганизации, "ПолноеНаименование,ЮридическийАдрес");
    ОбластьМакета.Параметры.АдресПоставщика = ПредставлениеПоставщика;
    СведенияОбОрганизации   = УправлениеКонтактнойИнформацией.СведенияОЮрФизЛице(Выборка.Получатель, Выборка.Дата);
    ПредставлениеПолучателя = ФормированиеПечатныхФорм.ОписаниеОрганизации(СведенияОбОрганизации, "ПолноеНаименование,ЮридическийАдрес");
    ОбластьМакета.Параметры.АдресПолучателя = ПредставлениеПолучателя;

    //Вывод заголовка
    ОбластьМакета.Параметры.НомерАкта = "Акт № " + ОбщегоНазначения.ПолучитьНомерНаПечать(Выборка);//"/"+Выборка.НомерСтроки
    ВидВзаиморасчетов = СокрЛП(Выборка.ВидВзаиморасчетов) ;   
    ОбластьМакета.Параметры.Услуга ="по "+ СокрЛП(Выборка.Товар) + " за " + Формат(Выборка.Дата, "ДФ=' ММММ гггг'")+ " г.";
    //ОбластьМакета.Параметры.ДатаОказания = "за" + Формат(Выборка.Дата, "ДФ=' ММММ гггг'")+ " г.";
            ОбластьМакета.Параметры.КонецМ = Формат(КонецМесяца(Выборка.Дата), "ДФ='дд ММММ гггг'")+ " г.";

    //Вывод представителей и номера договора
    Заказчик = Выборка.Заказчик;
    Исполнитель = Выборка.Исполнитель;
            ДолжностьЗаказчик = Выборка.Заказчик.ТекущаяДолжностьОрганизации;
    ДолжностьИсполнитель = Выборка.Исполнитель.ТекущаяДолжностьОрганизации;
    Поставщик = Выборка.Поставщик;
        Получатель = Выборка.Получатель;
    Договор = Выборка.ДоговорКонтрагента.Номер;
    ДатаДоговора = Выборка.ДоговорКонтрагента.Дата;
    ОбластьМакета.Параметры.Представление = "Мы, нижеподписавшиеся, представитель "  + Поставщик.НаименованиеСокращенное +" "+ Исполнитель.Наименование + " с одной стороны, и представитель " + Получатель.Наименование + " "  + Заказчик.Наименование +" с другой стороны, составили настоящий Акт о том, что Подрядчик сдал, а Заказчик принял выполненые работы в соответствии с договором №" + Договор +" от " + Формат(ДатаДоговора, "ДФ='дд.ММ.гггг'");

    // Вывести табличную часть
    ОбластьМакета.Параметры.Заполнить(Выборка);
    //ОбластьМакета.Параметры.НомерСтроки = 1;
    ОбластьМакета.Параметры.Товар = СокрЛП(Выборка.Товар);
    Сумма    = Выборка.Сумма;
    СуммаНДС = Выборка.СуммаНДС;
    Единицы = "(" + Выборка.ЕдиницаИзмерения + ".)";
    ОбластьМакета.Параметры.Единицы = Единицы;
    ОбластьМакета.Параметры.Всего = ОбщегоНазначения.ФорматСумм(Сумма);
            Если Выборка.УчитыватьНДС Тогда

    Если СуммаНДС <> 0 Тогда
    ОбластьМакета.Параметры.ВсегоНДС = ОбщегоНазначения.ФорматСумм(СуммаНДС);
    СуммаСНДС = Сумма + СуммаНДС;
    //ОбластьМакета.Параметры.НДС      = ?(Выборка.СуммаВключаетНДС, "В том числе НДС", " Сумма НДС");
    ОбластьМакета.Параметры.ВсегоСНДС = ОбщегоНазначения.ФорматСумм(СуммаСНДС);
    Иначе
    ОбластьМакета.Параметры.ВсегоНДС = "-";
    //ОбластьМакета.Параметры.НДС      = "Без налога (НДС)";
    КонецЕсли;

    КонецЕсли;

    Если Выборка.СуммаВключаетНДС Тогда
    СуммаСНДС=Сумма;
    ОбластьМакета.Параметры.ВсегоСНДС = ОбщегоНазначения.ФорматСумм(СуммаСНДС);
    КонецЕсли;

    // Cуммы прописью
    СуммаКПрописи = Сумма + ?(Выборка.СуммаВключаетНДС, 0, СуммаНДС);
    ОбластьМакета.Параметры.ИтоговаяСтрока ="Всего оказано услуг на сумму: " + ОбщегоНазначения.СформироватьСуммуПрописью(СуммаКПрописи, мВалютаРегламентированногоУчета); //+ ОбщегоНазначения.ФорматСумм(СуммаКПрописи, мВалютаРегламентированногоУчета);
    Если Выборка.УчитыватьНДС Тогда
    СуммаКПрописи = СуммаНДС;
    ОбластьМакета.Параметры.ИтоговаяСтрокаНДС =" В т.ч. НДС - " + ОбщегоНазначения.СформироватьСуммуПрописью( СуммаКПрописи, мВалютаРегламентированногоУчета);// ОбщегоНазначения.ФорматСумм(СуммаКПрописи,мВалютаРегламентированногоУчета);
    Иначе
    ОбластьМакета.Параметры.ИтоговаяСтрокаНДС =" Без налога НДС.";
    КонецЕсли;

    //Поля для росписи
    ОбластьМакета.Параметры.ДолжностьИсполнителя = ДолжностьИсполнитель;
    ОбластьМакета.Параметры.ДолжностьЗаказчика = ДолжностьЗаказчик;
    ОбластьМакета.Параметры.ПоставщикКр =  Поставщик.НаименованиеСокращенное;
    ОбластьМакета.Параметры.ПолучательКр = Получатель.Наименование;
    ОбластьМакета.Параметры.Заказчик = Заказчик;
    ОбластьМакета.Параметры.Исполнитель = Исполнитель;
            //ОбластьМакета.Параметры.Подрядчик = Поставщик.Префикс + " ' " + Поставщик.НаименованиеСокращенное + " ' ";
            ТабДокумент.ВывестиГоризонтальныйРазделительСтраниц();
    ТабДокумент.Вывести(ОбластьМакета);

    КонецЦикла;


    Возврат ТабДокумент;

    КонецФункции // ПечатьАктовОбОказанииУслуг()

    Добавлено через 4 минуты и 49 секунд:
    Подозреваю,что косяк где-то в

    ОбластьМакета.Параметры.ИтоговаяСтрока ="Всего оказано услуг на сумму: " + ОбщегоНазначения.СформироватьСуммуПрописью(СуммаКПрописи, мВалютаРегламентированногоУчета);



    Добавлено через 3 минуты и 45 секунд:
    Разобрался, косяк был в мВалютаРегламентированогоУчета

    вставил в код

    мВалютаРегламентированногоУчета = Константы.ВалютаРегламентированногоУчета.Получить();

    и все ок заработало.
  • Доброго времени суток и всех влюбленных с праздником, вот у меня любовь с 1С пока что 1-0 в её пользу... Есть неплохая книга с примерами Радченко, но вот выполнять, как мартышка, половину, не понимая значения выполненого, не очень интересно, когда-то очень давно программировал в Бейсике, помогает порой... Но большинство не совсем понятно: что в данный момент происходит, зачем и как! Естесственно, рыскаю в книгах, приходит какое-то понимание, но процесс такого самообразования происходит предельно медленно. Если есть кто терпеливый объяснить мне суть происходящего, прошу помочь в этом, от себя обещаю постараться быстро схватывать...
    Итак, есть такая функция в общем модуле:

    Код: (e1cv8)
    Функция РозничнаяЦена(АктуальнаяДата, ЭлементНоменклатуры) Экспорт 

    // Создать вспомогательный объект Отбор
    Отбор = Новый Структура("Номенклатура",ЭлементНоменклатуры);
      
    // Получить актуальные значения ресурсов регистра
    ЗначенияРесурсов = РегистрыСведений.Цены.ПолучитьПоследнее(АктуальнаяДата, Отбор);

    Возврат ЗначенияРесурсов.Цена;

    КонецФункции
    С первой строчкой пока вопросов нет- ясно, а вот вторая:
    Отбор = Новый Структура("Номенклатура",ЭлементНоменклатуры);

    Сразу за знаком = я теряю нить ясности, что означает и как работает: Новый, Структура, а также элементы в скобках, почему первый в кавычках (и что это дает)
    Пока остановимся на этом, добросердечные, помогите-разъясните :)
  • Платформа 8.2

    Конфа БП 2.0.25.5

    Если не вдаваться в подробности, то нужен отчет по определенному дописанному регистру. При этом в отчете фигурируют разные промежутки времени (с15.09.10 по 15.10.10; с 15.10.10 по 15.12.10 ; с 15.12.10 по 15.02.11; с 15.02.11 по 15.06.11)

    Пытаемся решить следующим образом:

    С помощью универсального отчета формируем отчет за первый промежуток, пишем в файл, потом за второй промежуток, дописываем в тот же файл, и т. д. После последнего сохраняем файл в Exel и открываем.

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



    Все три шага реализуются нажатием на разные кнопки в форме отчета.


    Шаг 1.

    Код: (e1cv8)
    //Пишем первый отчет в файл

    ТабДок = ЭлементыФормы.Результат;
     ТабДок.Записать("C:\temp\123",типфайлатабличногодокумента.mxl);

    Шаг 2.

    Код: (e1cv8)
    //Дописываем

    ТабДок = ЭлементыФормы.Результат;

    //Убираем столбец с контрагентами, так как он уже есть
     Область = ТабДок.Область("R4C1:R500C1");
     Смещать = ТипСмещенияТабличногоДокумента.ПоГоризонтали;
     ТабДок.УдалитьОбласть(Область, Смещать);



    ТабДокСтар = Новый ТабличныйДокумент;
     ИмяФайла = "C:\temp\123";
     ТабДокСтар.Прочитать(ИмяФайла);
     ТабДокСтар.Присоединить(ТабДок);
    ТабДокСтар.Записать(ИмяФайл,типфайлатабличногодокумента.mxl);

    Шаг 3.

    Код: (e1cv8)
    //Указываем куда все это сохранить и открываем

    ТабДокФин = Новый ТабличныйДокумент;
     ТабДокСтар = Новый ТабличныйДокумент;
     ИмяФайла = "C:\temp\123";
     ТабДокСтар.Прочитать(ИмяФайла);
     ИмяФайла2 = ПолучитьИмяФайлаExcel(); //Эта функция работает нормально, здесь ее код не привожу
     ТабДокФин.Записать(ИмяФайла2,типфайлатабличногодокумента.xls);
     ЗапуститьПриложение(ИмяФайла2);
  • Программирование :: Программирование 1С :: 1С 8.2: Управляемое приложение
  • Здравствуйте!

    Помогите разобраться с проводкой акциза. 1с 8.2 редакции 1.1.11.1 не идут проводки со счета 90.04 на счет 68.03 как реализовать вопрос.
  • Операционные системы :: Windows
  • Кто какие средства может порекомендовать для выполнения backup файлов из папки?

    Требования:
    1) Оперативная работа (не по ночам, а параллельно с другой активностью юзера).
    2) Управление через API - запуск процесса для определённых папок и файлов из прикладной программы и возможность синхронизации прикладной программы с процессом создания резервной копии. Желательно наличие SDK. На худой конец настройка процесса через командную строку или файл конфигурации и управление через сигналы.
    3) Возможность работы в фоновом режиме с низким приоритетом, чтобы не тормозило систему и другие прикладные программы.
    4) Поддержка хранилищ не только на логических дисках Windows, но и на FTP, возможность "прожига" DVD.
    5) Поддержка версий Windows от XP и выше, 32/64 бита.
  • Операционные системы :: Unix и другие
  • Как установить Linux, чтобы не было графических окон -
    одна командная строка и компилятор GCC был установлен?
    Ставлю на одноплатный комп, там диск маленький.
    Заходил на http://www.linuxfromscratch.org - там мало
    чего понял.
    Спастибо за ответ!
  • Практические разделы :: Железо
  • Имеется PCMCIA flash-диск SLATA256MM1UI-S. Есть нужда использовать его с прибором ANT-20. ОС в приборе - Windows 95 и естественно диска не видит. Помогите драйвером или ссылкой для сего чуда.

А теперь прощаемся с Вами до следующего выпуска.


С уважением, команда Клуба.


В избранное