Thursday, December 24, 2015

Получение PDF файла ЕН Новой почты

Простая функция по получению pdf для печати от новой почты

Функция вернутьPDF(знач DocumentRef) Экспорт
 СтрокаJSON = Новый ЗаписьJSON;
 СтрокаJSON.УстановитьСтроку();
 СтруктураЗнч = новый Структура;
 СтруктураЗнч.Вставить("apiKey","апи код новой почты");
 СтруктураЗнч.Вставить("modelName","InternetDocument");
 СтруктураЗнч.Вставить("calledMethod","printMarkings"); 
 Соот = Новый Соответствие;
 массивДокументов = новый Массив;
 массивДокументов.Добавить(DocumentRef);
 Соот.Вставить("DocumentRefs",массивДокументов);
 СтруктураЗнч.Вставить("methodProperties",Соот); 
 Настройка = Новый НастройкиСериализацииJSON;
 
 ЗаписатьJSON(СтрокаJSON, СтруктураЗнч,); 
 исхстрокаJSON = СтрокаJSON.Закрыть();
 
 
 Защищенное = Новый ЗащищенноеСоединениеOpenSSL;
 СоединениеHTTP = Новый HTTPСоединение("api.novaposhta.ua",,,,,,Защищенное);
 ЗапросHTTP = Новый HTTPЗапрос("/v2.0/json/");
 ЗапросHTTP.УстановитьТелоИзСтроки(исхстрокаJSON,КодировкаТекста.UTF8); 
 ЗапросHTTP.Заголовки.Вставить("Host","api.novaposhta.ua"); 
 ЗапросHTTP.Заголовки.Вставить("Content-Type","application/json"); 
 
 Результат = СоединениеHTTP.ВызватьHTTPМетод("POST",ЗапросHTTP);
 //.Получить(ЗапросHTTP);
 
 ВремФайлPDF = ПолучитьИмяВременногоФайла("pdf");
 ДВ = Результат.ПолучитьТелоКакДвоичныеДанные();
 ДВ.Записать(ВремФайлPDF);
 Возврат ВремФайлPDF;
КонецФункции

Tuesday, December 15, 2015

Работа с byte[]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CentralLib.ConnectionFP;
using CentralLib.DefaultPortCom;


namespace TestComm
{
    class Program
    {
        static void Main(string[] args)
        {
            byte DLE = 0x10;
            byte STX = 0x02;
            byte ETX = 0x03;
            byte[] bBytes = new byte[] {DLE, STX };
            byte[] eBytes = new byte[] {DLE, ETX };

            byte[] test1 = new byte[] { 00, 00, 16, 2, 0, 27, 1, 1, 97, 130, 16, 16, 16, 16, 3, 16, 16, 16, 3, 28, 170 };
           PrintByteArray(test1);
            int positionPacketBegin = ByteSearch(test1, new byte[] { DLE, STX });
            Console.WriteLine(positionPacketBegin);
            int positionPacketEnd = 0;
            int tCurrentPos = positionPacketBegin;
            int tPostEnd = -1;
            do
            {
                tCurrentPos++;                
                tPostEnd = ByteSearch(test1, new byte[] { 16, 3 }, tCurrentPos); 
                if (tPostEnd != -1)
                {
                    tCurrentPos = tPostEnd;
                    
                    if (test1[tPostEnd - 1] != DLE)
                    {
                        
                        break;
                    }
                    else if ((test1[tPostEnd - 1] == DLE) && (test1[tPostEnd - 2] == DLE))
                    {
                        positionPacketEnd = tPostEnd;
                       // break;
                    }                        
                }                
            } while  (tCurrentPos < test1.Length) ;
            Console.WriteLine(positionPacketEnd);
            var unsigned = new byte[positionPacketEnd- positionPacketBegin+4];
            Buffer.BlockCopy(test1, positionPacketBegin, unsigned, 0, positionPacketEnd - positionPacketBegin+4);
            PrintByteArray(unsigned);
            Console.ReadKey();
            //DefaultPortCom initialPort = new DefaultPortCom(4);
            //ConnectionFP connFP = new ConnectionFP(initialPort);
            //connFP.Open();
            //Provision proConn = new Provision(connFP);



            //proConn.ExchangeData(new byte[] { 16, 2, 0, 27, 1, 1, 97, 130, 16, 3, 28, 170 });
            //Console.ReadKey();

            //proConn.Dispose();
            //connFP.Close();

        }


        static void PrintByteArray(byte[] bytes)
        {
            var sb = new StringBuilder("new byte[] { ");
            foreach (var b in bytes)
            {
                sb.Append(b + ", ");
            }
            sb.Append("}");
            Console.WriteLine(sb.ToString());
        }

        static int ByteSearch(byte[] searchIn, byte[] searchBytes, int start = 0)
        {
            int found = -1;
            bool matched = false;
            //only look at this if we have a populated search array and search bytes with a sensible start
            if (searchIn.Length > 0 && searchBytes.Length > 0 && start <= (searchIn.Length - searchBytes.Length) && searchIn.Length >= searchBytes.Length)
            {
                //iterate through the array to be searched
                for (int i = start; i <= searchIn.Length - searchBytes.Length; i++)
                {
                    //if the start bytes match we will start comparing all other bytes
                    if (searchIn[i] == searchBytes[0])
                    {
                        if (searchIn.Length > 1)
                        {
                            //multiple bytes to be searched we have to compare byte by byte
                            matched = true;
                            for (int y = 1; y <= searchBytes.Length - 1; y++)
                            {
                                if (searchIn[i + y] != searchBytes[y])
                                {
                                    matched = false;
                                    break;
                                }
                            }
                            //everything matched up
                            if (matched)
                            {
                                found = i;
                                break;
                            }

                        }
                        else
                        {
                            //search byte is only one bit nothing else to do
                            found = i;
                            break; //stop the loop
                        }

                    }
                }

            }
            return found;
        }


    }
}

Sunday, November 22, 2015

Как в C# сделать подсчет контрольной суммы CRC16 используя CCITT2 -полином

Что то везет в последнее время на "качество оформленную документацию". И вот новая "стезя", работа с ИКС-маркетом и драйвером под виндоуз (хотя сейчас стало интересно, исправили ли они глюки в своем, может я даром долбаюсь????)

Вот вырезке из их документации:
Контрольная сумма CRC16 использует CCITT2
-полином (х16 + х12 + х5
+ 1) и расчитывается по
полям Номер, Код, Параметры, CS и ETX без дублирующих и заключительного DLE. В ответном пакете
CRC16 подсчитывается аналогично.
ЭККР записывает полученный Номер и Код в ответное сообщение. Если ЭККР получает
сообщение, в котором совпадают значения полей Номер и Код со значениями предыдущего
сообщения, то он не выполняет команду, а повторяет передачу предыдущего сообщения.
Пример вычисления CRC16 на Си:
void CalcCRC16(BYTE *Buf, WORD Size, WORD *CRC16)
{char V;
while(Size--) {
V = *Buf++;
INT_HI(*CRC16) ^= V;
V = (INT_HI(*CRC16) << 4) ^ INT_HI(*CRC16); INT_HI(*CRC16) = (V >> 4) ^ (V << 3) ^ INT_LO(*CRC16); INT_LO(*CRC16) = (V >> 5) ^ V;
}
}
Пример вычисления CRC16 на Паскале:
function CalcCRC16(DataByte: Byte; CRC16: word): word;
var
a:word;
begin
CRC16 := CRC16 xor DataByte;
a:=(CRC16 xor (CRC16 shl 4)) and $00FF;
Result:=(CRC16 shr 8) xor (a shl 8) xor (a shl 3) xor (a shr 4);
end;
Вопрос, что так тяжело описать что и зачем используете??? Какой полином??? В общем спасибо за сутки разбора...
Решение было сделано так:
0. спасибо утилите serial port monitor, за то что удалось посмотреть, как обмениваться между собой аппарат и утилита ИКС
1.найден был сайт с online калькулятором расчета CRC.
2. Благодаря калькулятору удалось понять какой метод шифрования необходимо использовать - CRC-CCITT (Kermit), ИКС что так сложно описать???
3. Найдено решение спасибо гугл и stackoverflow

оставлю код для необходимости:




using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            byte ETX = 0x03;
            byte DLE = 0x10;
            byte STX = 0x02;
            byte ASK = 0x06;
            //Crc16Ccitt crc16 = new Crc16Ccitt(x);
            //    10 02 46 00 ba 10 03 a8 a8                        ..F.є..ЁЁ        
            //    10 02 56 00 aa 10 03 98 fe                        ..V.Є..˜ю 
            //    10 02 60 00 a0 10 03 80 04..`. ..Ђ. 
            //    10 02 6b 32 00 00 00 00 63 10 03 3a e8            ..k2....c..:и
            //    10 02 6a 00 96 10 03 5c 3a                        ..j.–..\:        
            //    10 02 73 32 00 00 09 00 52 10 03 e7 c8            ..s2....R..зИ    
            //    10 02 5f 32 00 00 09 00 66 10 03 b7 94            .._2....f..·”    
            //    10 02 74 00 8c 10 03 5e 3f                        ..t.Њ..^?        
            //    10 02 75 32 00 00 00 00 59 10 03 9d c8            ..u2....Y..ќИ    
            //    10 02 76 32 00 00 01 00 57 10 03 e6 c4            ..v2....W..жД    

            //Array<byte[]> myList = new Array<byte[]>();            
            //myList.Add({ 0x10, 0x02, 0x46, 0x00, 0xba, 0x10, 0x03, 0xa8, 0xa8 });
            //byte[] temp = { 0x10, 0x02, 0x56, 0x00, 0xaa, 0x10, 0x03, 0x98, 0xfe }; 
            ArrayList myList = new ArrayList();
            byte[] arrayofbytes = { 0x10, 0x02, 0x46, 0x00, 0xba, 0x10, 0x03, 0xa8, 0xa8 };            
            myList.Add(arrayofbytes);
            arrayofbytes = new byte[] { 0x10, 0x02, 0x56, 0x00, 0xaa, 0x10, 0x03, 0x98, 0xfe };
            myList.Add(arrayofbytes);
            arrayofbytes = new byte[] { 0x10, 0x02, 0x76, 0x32, 0x00, 0x00, 0x01, 0x00, 0x57, 0x10, 0x03, 0xe6, 0xc4 };
            myList.Add(arrayofbytes);
            byte[] bytebegin = { DLE, STX};
            byte[] byteend = {DLE, ETX};

            Crc16 testCRC16 = new Crc16(Crc16Mode.CcittKermit);

            //ushort max = ushort.MaxValue;
            //for (ushort x = 0; x <= max - 1; x++)
            //{
                //Console.WriteLine(x);
                foreach (byte[] tempa in myList)
                {
                    //Console.WriteLine(PrintByteArray(tempa));
                    byte[] tempb = returnWithOutDublicateETX(tempa);
                    var searchBegin = PatternAt(tempb, bytebegin);
                    if (searchBegin == null)
                        continue;

                    var searchEnd = PatternAt(tempb, byteend);
                    if (searchEnd == null)
                        continue;
                        
                    var newArr = tempb.Skip((int)searchBegin+2).Take((int)searchEnd-2).ToArray();
                                                           
                    byte[] a = new byte[newArr.Length+1];
                    newArr.CopyTo(a, 0);                    
                    a[newArr.Length] = ETX;
                    //Console.WriteLine(PrintByteArray(a));

                    var control = tempb.Skip((int)searchEnd+2).Take(2).ToArray();
                    //Console.WriteLine(PrintByteArray(control));


                    //byte[] crc = BitConverter.GetBytes(compute_fcs(a, x));
                    
                    byte[] crc = testCRC16.ComputeChecksumBytes(a);

                    if ((crc[0] == control[0]) && (crc[1] == control[1]))                    
                    {
                        Console.WriteLine(PrintByteArray(tempa));
                        Console.WriteLine(PrintByteArray(a));
                        Console.WriteLine(PrintByteArray(control));
                       // Console.WriteLine(x);                        
                        Console.WriteLine(PrintByteArray(crc));
                        Console.ReadKey();
                       //break;
                    }
                }
                //break;
            //}
            Console.WriteLine("The End!!!!");
            Console.ReadKey();
        }

        static byte[] returnWithOutDublicateETX(byte[] source)
        {
            return returnWithOutDublicate(source, new byte[] { 0x10, 0x10 });
        }

        static byte[] returnWithOutDublicate(byte[] source, byte[] pattern)
        {
            
            List<byte> tReturn  =new List<byte>();
            int sLenght = source.Length;
            for (int i = 0; i < sLenght; i++)
            {
                if (source.Skip(i).Take(pattern.Length).SequenceEqual(pattern))
                {
                    tReturn.Add(source[i]);
                    i++;                    
                }
                else
                {
                    tReturn.Add(source[i]);
                }
            }
            return (byte[])tReturn.ToArray();
        }

        static int? PatternAt(byte[] source, byte[] pattern)
        {
            for (int i = 0; i < source.Length; i++)
            {
                if (source.Skip(i).Take(pattern.Length).SequenceEqual(pattern))
                {
                    return i;
                }
            }
            return null;
        }

        static string PrintByteArray(byte[] bytes)
        {
            var sb = new StringBuilder("new byte[] { ");
            foreach (var b in bytes)
            {
                sb.AppendFormat("{0:x2}", b);
                sb.Append(" ");
            }
            sb.Append("}");
            return sb.ToString();
        }

        ///

        public enum Crc16Mode : ushort { Standard = 0xA001, CcittKermit = 0x8408 }

        public class Crc16
        {
            static ushort[] table = new ushort[256];

            public ushort ComputeChecksum(params byte[] bytes)
            {
                ushort crc = 0;
                for (int i = 0; i < bytes.Length; ++i)
                {
                    byte index = (byte)(crc ^ bytes[i]);
                    crc = (ushort)((crc >> 8) ^ table[index]);
                }
                return crc;
            }

            public byte[] ComputeChecksumBytes(params byte[] bytes)
            {
                ushort crc = ComputeChecksum(bytes);
                return BitConverter.GetBytes(crc);
            }

            public Crc16(Crc16Mode mode)
            {
                ushort polynomial = (ushort)mode;
                ushort value;
                ushort temp;
                for (ushort i = 0; i < table.Length; ++i)
                {
                    value = 0;
                    temp = i;
                    for (byte j = 0; j < 8; ++j)
                    {
                        if (((value ^ temp) & 0x0001) != 0)
                        {
                            value = (ushort)((value >> 1) ^ polynomial);
                        }
                        else
                        {
                            value >>= 1;
                        }
                        temp >>= 1;
                    }
                    table[i] = value;
                }
            }
        }


        ////

    }

}

Monday, October 19, 2015

Source code beautifier / syntax highlighter – convert code snippets to HTML « hilite.me

Форматер кода в читаемый html
Source code beautifier / syntax highlighter – convert code snippets to HTML « hilite.me:

'via Blog this'

Уведомления пользователей по мылу о смене пароля в домене

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

#################################################################################################################
# 
# Version 1.3 April 2015
# Robert Pearman (WSSMB MVP)
# TitleRequired.com
# Script to Automated Email Reminders when Users Passwords due to Expire.
#
# Requires: Windows PowerShell Module for Active Directory
#
# For assistance and ideas, visit the TechNet Gallery Q&A Page. http://gallery.technet.microsoft.com/Password-Expiry-Email-177c3e27/view/Discussions#content
#
##################################################################################################################
# Please Configure the following variables....
$smtpServer="rl-mx-1.rl.int"
$expireindays = 10
$from = "Administrator <dyachok@rl.ua>"
$logging = "Enabled" # Set to Disabled to Disable Logging or Enabled
$logFile = "c:\log\mylog.csv" # ie. c:\mylog.csv
$testing = "Disabled" # Set to Disabled to Email Users
$testRecipient = "dyachok@rl.ua"
$date = Get-Date -format ddMMyyyy
#
###################################################################################################################

# Check Logging Settings
if (($logging) -eq "Enabled")
{
    # Test Log File Path
    $logfilePath = (Test-Path $logFile)
    if (($logFilePath) -ne "True")
    {
        # Create CSV File and Headers
        New-Item $logfile -ItemType File
        Add-Content $logfile "Date,Name,EmailAddress,DaystoExpire,ExpiresOn"
    }
} # End Logging Check

# Get Users From AD who are Enabled, Passwords Expire and are Not Currently Expired
Import-Module ActiveDirectory
$users = get-aduser -filter * -properties Name, PasswordNeverExpires, PasswordExpired, PasswordLastSet, EmailAddress |where {$_.Enabled -eq "True"} | where { $_.PasswordNeverExpires -eq $false } | where { $_.passwordexpired -eq $false }
$DefaultmaxPasswordAge = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge

# Process Each User for Password Expiry
foreach ($user in $users)
{
    $Name = $user.Name
    $emailaddress = $user.emailaddress
    $passwordSetDate = $user.PasswordLastSet
    $PasswordPol = (Get-AduserResultantPasswordPolicy $user)
    # Check for Fine Grained Password
    if (($PasswordPol) -ne $null)
    {
        $maxPasswordAge = ($PasswordPol).MaxPasswordAge
    }
    else
    {
        # No FGP set to Domain Default
        $maxPasswordAge = $DefaultmaxPasswordAge
    }

  
    $expireson = $passwordsetdate + $maxPasswordAge
    $today = (get-date)
    $daystoexpire = (New-TimeSpan -Start $today -End $Expireson).Days
        
    # Set Greeting based on Number of Days to Expiry.

    # Check Number of Days to Expiry
    $messageDays = $daystoexpire

    if (($messageDays) -ge "1")
    {
        $messageDays = "в течении " + "$daystoexpire" + " дней."
    }
    else
    {
        $messageDays = "сегодня."
    }

    # Email Subject Set Here

  

    $subject="Ваш пароль устареет $messageDays"

    $encoding = [System.Text.Encoding]::UTF8

    # Email Body Set Here, Note You can use HTML, including Images.
    $body ="
    Уважаемый $name,
    <p> Рекомендуется изменить ваш пароль, пароль необходимо изменить $messageDays<br>
    Чтобы изменить пароль на доменном компьютере, нажмите клавиши Ctlr+ALt+Delete <br>
    (или же вы работаете на удаленно рабочем столе (терминале), нажимет клавиши Ctlr+ALt+End) <br>
    и выберите 'Сменить пароль...' <br>
    <p>С уважением, robot<br> 
    </P>"

   
    # If Testing Is Enabled - Email Administrator
    if (($testing) -eq "Enabled")
    {
        $emailaddress = $testRecipient
    } # End Testing

    # If a user has no email address listed
    if (($emailaddress) -eq $null)
    {
        $emailaddress = $testRecipient    
    }# End No Valid Email

    # Send Email Message
    if (($daystoexpire -ge "0") -and ($daystoexpire -lt $expireindays))
    {
         # If Logging is Enabled Log Details
        if (($logging) -eq "Enabled")
        {
            Add-Content $logfile "$date,$Name,$emailaddress,$daystoExpire,$expireson" 
        }
        # Send Email Message
        Send-Mailmessage -smtpServer $smtpServer -from $from -to $emailaddress -subject $subject -body $body -bodyasHTML -priority High  -Encoding $encoding

    } # End Send Message
    
} # End User Processing



# End

Saturday, October 17, 2015

Скрипт запуска необходимых Jobs из агента SQL

Возникла задача когда на MS SQL сервере необходимо перезапустить часть job, вручную делать эту работу не хотелось, вот реализовал скрипт по работе:







DECLARE @SQL NVARCHAR(MAX)
DECLARE @job SYSNAME

DECLARE jobs_cursor CURSOR
FOR
SELECT 'EXEC msdb.dbo.sp_start_job ''' + s.NAME + ''''
FROM msdb..sysjobs s
WHERE s.NAME LIKE 'Reset%'

OPEN jobs_cursor

FETCH NEXT
FROM jobs_cursor
INTO @job

WHILE @@Fetch_Status = 0
BEGIN
 PRINT @job

 EXEC sp_executesql @job_name = @job

 FETCH NEXT
 FROM jobs_cursor
 INTO @job
END

CLOSE jobs_cursor

DEALLOCATE jobs_cursor



Основная схма работы скрипта, найти задачу которая начинается на 'Reset' и запустить ее.

Thursday, October 8, 2015

Проблемы в XCODE с GIT

Столкнулся с проблемой в работе с XCODE на Маке и GIT, после перегрузки слетали настройки
git config --global user.name "Mikola Dyachok"
git config --global user.email "ndyachok@gmail.com"
если в первый раз все отработало нормально, то на следующий раз при добавление в GIT возникала проблема и уже не решалась запуском команд.
Решение добавить в файл config который находить в директории .git следующие строки:

[user]
name = Nike Dyachok
email = ndyachok@gmail.com


Monday, October 5, 2015

Thursday, October 1, 2015

1С статьи - 1CWorks.com

Как настроить HTTP сервер на 1С.
1С статьи - 1CWorks.com:
Одна из редких статей где написано как и что просто сделать.
Делаем JSON и новые обмены

'via Blog this'

Wednesday, August 19, 2015

Доработка прав доступа в УТ11

Постоянно донимали пользователи со своими правами и разрешениями. В связи с этим пришлось доработать УТ11 на ускорение ввода разрешений или блокировок.

Вот и сделал себе "кайф", а пользователям радость.
Повозился пока нашел удобный вариант получения из ПВХ (Планов видов характеристик) необходимый мне объект и как итог его форму выбора
Метаданные.НайтиПоТипу(ТекущийВидДоступа.ТипЗначения.Типы()[0]).ОсновнаяФормаДляВыбора.ПолноеИмя()

И добавил следующий код

&НаКлиенте
Процедура КомандаПодбор(Команда) 
 ПараметрыФормы = Новый Структура;
 ПараметрыФормы.Вставить("РежимВыбора", Истина);
 ПараметрыФормы.Вставить("ЗакрыватьПриВыборе", Ложь);
 ПараметрыФормы.Вставить("МножественныйВыбор",Истина);
 ОткрытьФорму(ВернутьТекущуюФормуВЫбора(),ПараметрыФормы,Элементы.ЗначенияДоступа);
 //Метаданные.НайтиПоТипу(ТекущийВидДоступа.ТипЗначения.Типы()[0]).ПолноеИмя()
 //Если Метаданные.Справочники
КонецПроцедуры

Функция ВернутьТекущуюФормуВЫбора() 
 Возврат Метаданные.НайтиПоТипу(ТекущийВидДоступа.ТипЗначения.Типы()[0]).ОсновнаяФормаДляВыбора.ПолноеИмя();
КонецФункции

&НаКлиенте
Процедура ЗначениеДоступаОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
 
 Если ВыбранноеЗначение = Тип("СправочникСсылка.Пользователи") ИЛИ
      ВыбранноеЗначение = Тип("СправочникСсылка.ГруппыПользователей") Тогда
 
  СтандартнаяОбработка = Ложь;
  НачальноеЗначение = Элементы.ЗначенияДоступа.ТекущиеДанные.ЗначениеДоступа;
  ОткрытьФорму("Справочник.Пользователи.ФормаВыбора", Новый Структура("ВыборГруппПользователей, ТекущаяСтрока", Истина, НачальноеЗначение), Элемент);
 
 ИначеЕсли ВыбранноеЗначение = Тип("СправочникСсылка.ВнешниеПользователи") ИЛИ
           ВыбранноеЗначение = Тип("СправочникСсылка.ГруппыВнешнихПользователей") Тогда
 
  СтандартнаяОбработка = Ложь;
  НачальноеЗначение = Элементы.ЗначенияДоступа.ТекущиеДанные.ЗначениеДоступа;
  ОткрытьФорму("Справочник.ВнешниеПользователи.ФормаВыбора", Новый Структура("ВыборГруппВнешнихПользователей, ТекущаяСтрока", Истина, НачальноеЗначение), Элемент);
 КонецЕсли;
 
 тМасс = Новый Массив;
 Если ТипЗнч(ВыбранноеЗначение) = Тип("Массив") тогда
  тМасс.Добавить(ВыбранноеЗначение);
 Иначе
  тМасс = ВыбранноеЗначение;
 КонецЕсли;
 
 Если ТипЗнч(ВыбранноеЗначение) = Тип("Массив") тогда
  Для Каждого ВыбранныйЭлемент Из ВыбранноеЗначение Цикл
   Если Объект.ЗначенияДоступа.НайтиСтроки(Новый Структура("ЗначениеДоступа",ВыбранныйЭлемент)).Количество() = 0  Тогда
    НоваяСтрока = Объект.ЗначенияДоступа.Добавить();
    НоваяСтрока.ЗначениеДоступа = ВыбранныйЭлемент;
    НоваяСтрока.ВидДоступа = ТекущийВидДоступа;
   КонецЕсли;
  КонецЦикла;
 КонецЕсли;
 
КонецПроцедуры


В общем пока все работает.

Thursday, August 6, 2015

Перенос остатков на склад после включения в бухгалтерии "Ввести складской учет"

В общем тривиальная задача, есть 1С Бухгалтерия 8.2 необходимо перебросить остатки на счетах после включения "Ввести складской учет".
В нете решения не нашел, делаю свое. Форма с 3 полями "На дату", "Организация", "На склад".
Задача тривиальная, но вот заставило задумать по работе с установкой субконто и работа с партиями.


Процедура КнопкаВыполнитьНажатие(Кнопка)
   
 
 Запрос = Новый Запрос;
 Запрос.Текст = 
  "ВЫБРАТЬ
  | ХозрасчетныйОстатки.Счет,
  | ХозрасчетныйОстатки.Субконто1,
  | ХозрасчетныйОстатки.Субконто2,
  | ХозрасчетныйОстатки.Субконто3,
  | ХозрасчетныйОстатки.Организация,
  | ХозрасчетныйОстатки.Валюта,
  | ХозрасчетныйОстатки.НалоговоеНазначение,
  | ХозрасчетныйОстатки.КоличествоОстаток КАК Количество,
  | ХозрасчетныйОстатки.СуммаОстаток КАК Сумма,
  | ХозрасчетныйОстатки.ВалютнаяСуммаОстаток КАК ВалютнаяСумма,
  | ХозрасчетныйОстатки.СуммаНУОстаток КАК СуммаНУ
  |ИЗ
  | РегистрБухгалтерии.Хозрасчетный.Остатки(
  |   &НаДату,
  |   ,
  |   ,
  |   Организация = &Организация
  |    И (ТИПЗНАЧЕНИЯ(Субконто1) = ТИП(Справочник.Склады)
  |     ИЛИ ТИПЗНАЧЕНИЯ(Субконто2) = ТИП(Справочник.Склады)
  |     ИЛИ ТИПЗНАЧЕНИЯ(Субконто3) = ТИП(Справочник.Склады))) КАК ХозрасчетныйОстатки";
 
 Запрос.УстановитьПараметр("НаДату",НачалоДня(НаДату));
 Запрос.УстановитьПараметр("Организация",Организация);
 
 РезультатЗапроса = Запрос.Выполнить();
 
 ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
 
 Операция = Документы.ОперацияБух.СоздатьДокумент();
 Операция.УстановитьНовыйНомер();
 Операция.Дата = НачалоДня(НаДату)-1;
 Операция.Организация = Организация;
 Операция.Содержание = "Корректировка остатков бух";
 Операция.Записать(); 
 Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
  НоваяЗапись  = Операция.Движения.Хозрасчетный.Добавить();
  НоваяЗапись.Активность = Истина;  
  НоваяЗапись.Регистратор = Операция.Ссылка;
  НоваяЗапись.ВалютаДт = ВыборкаДетальныеЗаписи.Валюта;
  НоваяЗапись.ВалютаКт = ВыборкаДетальныеЗаписи.Валюта;
  НоваяЗапись.ВалютнаяСуммаДт = ВыборкаДетальныеЗаписи.ВалютнаяСумма;
  НоваяЗапись.ВалютнаяСуммаКт = ВыборкаДетальныеЗаписи.ВалютнаяСумма;
  НоваяЗапись.КоличествоДт =  ВыборкаДетальныеЗаписи.Количество;
  НоваяЗапись.КоличествоКт =  ВыборкаДетальныеЗаписи.Количество;
  НоваяЗапись.НалоговоеНазначениеДт = ВыборкаДетальныеЗаписи.НалоговоеНазначение;
  НоваяЗапись.НалоговоеНазначениеКт = ВыборкаДетальныеЗаписи.НалоговоеНазначение;
  НоваяЗапись.Организация = Организация;
  НоваяЗапись.Сумма = ВыборкаДетальныеЗаписи.Сумма;
  НоваяЗапись.СуммаНУДт = ВыборкаДетальныеЗаписи.СуммаНУ;
  НоваяЗапись.СуммаНУКт = ВыборкаДетальныеЗаписи.СуммаНУ;
  НоваяЗапись.СчетДт = ВыборкаДетальныеЗаписи.Счет;
  НоваяЗапись.СчетКт = ВыборкаДетальныеЗаписи.Счет;
  УстановитьСубконтоКт(НоваяЗапись,ВыборкаДетальныеЗаписи.Субконто1);
  УстановитьСубконтоКт(НоваяЗапись,ВыборкаДетальныеЗаписи.Субконто2);
  УстановитьСубконтоКт(НоваяЗапись,ВыборкаДетальныеЗаписи.Субконто3);
  Если ТипЗнч(ВыборкаДетальныеЗаписи.Субконто1) = Тип("СправочникСсылка.Склады") тогда
   УстановитьСубконтоДт(НоваяЗапись,Склад);
  Иначе
   УстановитьСубконтоДт(НоваяЗапись,ВыборкаДетальныеЗаписи.Субконто1);
  КонецЕсли;
  
  Если ТипЗнч(ВыборкаДетальныеЗаписи.Субконто2) = Тип("СправочникСсылка.Склады") тогда
   УстановитьСубконтоДт(НоваяЗапись,Склад);
  Иначе
   УстановитьСубконтоДт(НоваяЗапись,ВыборкаДетальныеЗаписи.Субконто2);
  КонецЕсли;
  
  Если ТипЗнч(ВыборкаДетальныеЗаписи.Субконто3) = Тип("СправочникСсылка.Склады") тогда
   УстановитьСубконтоДт(НоваяЗапись,Склад);
  Иначе
   УстановитьСубконтоДт(НоваяЗапись,ВыборкаДетальныеЗаписи.Субконто3);
  КонецЕсли;
  
 КонецЦикла;
 //Операция.записать(); 
 Операция.ПолучитьФорму("ФормаДокумента").Открыть();
 
 

КонецПроцедуры

Функция УстановитьСубконтоДт(Проводка,ЗначениеСубконто)
 Для Каждого ВидСубконто Из Проводка.СчетДт.ВидыСубконто Цикл
     Если ВидСубконто.ВидСубконто.ТипЗначения.СодержитТип(ТипЗнч(ЗначениеСубконто)) тогда
         Проводка.СубконтоДт[ВидСубконто.ВидСубконто.Ссылка] = ЗначениеСубконто;
     КонецЕсли;
 КонецЦикла;
КонецФУнкции

Функция УстановитьСубконтоКт(Проводка,ЗначениеСубконто)
 Для Каждого ВидСубконто Из Проводка.СчетКт.ВидыСубконто Цикл
     //Если Строка(ТипЗнч(ЗначениеСубконто)) = Строка(ВидСубконто.ВидСубконто.ТипЗначения) Тогда
  Если ВидСубконто.ВидСубконто.ТипЗначения.СодержитТип(ТипЗнч(ЗначениеСубконто)) тогда
         Проводка.СубконтоКт[ВидСубконто.ВидСубконто.Ссылка] = ЗначениеСубконто;
     КонецЕсли;
 КонецЦикла;
КонецФУнкции



Процедура ПриОткрытии()
 //НаДату = НачалоМесяца(ТекущаяДата());
 НаДату =  Дата(2015,07,01);
 Склад = Справочники.Склады.НайтиПоНаименованию("Основной склад",Истина);
КонецПроцедуры

Thursday, July 16, 2015

1С управляемые формы и отображение картинки...

В 1С работают извращенцы, полные, вот мне честно хочется посмотреть тому дятлу который придумал работу в управляемых формах с картинками и спросить "Ты нормальный?"
Это под какой травкой такое надо было придумать....

В общем задача: отобразить на управляемой форме картинку, отобразить... Карл!!!!!

и итог 3 часа ковыряния как отобразить картинку.


В общем решение:

в управляемых формах принцип следующий:

Простой пример справочника с картинкой

Отображения картинки текущего элемента списка

В новой версии платформы 1С 8.2 работа с картинками производится отличным от предыдущих платформ методом, разобраться с которым без примеров сложно. Подробно можно прочитать в книге Разработка управляемого интерфейса глава 3.18. Работа с файлами и картинками. Примеры данной статья являются переработанными и дополненными примерами книги.

Картинка как и раньше (8.1) хранится в базе в реквизите (реквизите ТЧ) с типом ХранилищеЗначения, но записать данные в реквизит с этим типом обычном способом нельзя, запись производится в предопределенной процедуре «ПередЗаписьюНаСервере».

Для отображения картинки создается элемент формы поле картинки, данными для которого, является реквизит формы (с типом Строка(0)), содержащий навигационную ссылку на картинку (можно получить функцией «ПолучитьНавигационнуюСсылку») или адрес во временном хранилище (пол.ф. «ПоместитьФайл»)

Ниже приведен код части примера:

Код 1C v 8.2 УП
&НаКлиенте

Процедура ЗагрузитьФотографию(Команда)
Перем ВыбранноеИмя,АдресВременногоХранилища;
Если ПоместитьФайл(АдресВременногоХранилища, "", ВыбранноеИмя, Истина, УникальныйИдентификатор) Тогда
АдресКартинки = АдресВременногоХранилища;
Модифицированность = Истина;
КонецЕсли;
КонецПроцедуры

&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
Если ЭтоАдресВременногоХранилища(АдресКартинки) Тогда
ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресКартинки);
ТекущийОбъект.Фото = Новый ХранилищеЗначения(ДвоичныеДанные, Новый СжатиеДанных());
КонецЕсли;
КонецПроцедуры

&НаСервере
Процедура ПриЧтенииНаСервере(ТекущийОбъект)
АдресКартинки = ПолучитьНавигационнуюСсылку(ТекущийОбъект.Ссылка, "Фото");
КонецПроцедуры

&НаСервере
Процедура ПриЗаписиНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
Если ЭтоАдресВременногоХранилища(АдресКартинки) Тогда
УдалитьИзВременногоХранилища(АдресКартинки);
КонецЕсли;

АдресКартинки = ПолучитьНавигационнуюСсылку(ТекущийОбъект.Ссылка, "Фото");
КонецПроцедуры

В книге Разработка управляемого интерфейса используется дополнительно поле для сохранения имени файла оно необходимо если нужно чтобы программа запомнила из какой папки пользователь предпочитает добавлять или выгружать файлы.

В процедуре ПриЗаписиНаСервере на первый взгляд можно убрать код удаление из временного хранилища т.к. ф. ПоместитьФайл вызывается с параметром УникальныйИдентификатор формы т.е. объект хранилища будет существовать до закрытия формы, но рекумендуется освобождать ресурсы сразу (если пользователь загрузит картинку и нажмет записать, форма не закрыта и объект будет существовать до закрытия).

Взято тут

Monday, July 13, 2015

1C & REGEX Как упростить себе жизнь

Много времени экономит Regex, очень много, до него код моих программ превращался в монстроидальным и занимавшим не одну сотню строчек. Так что плюсы в нем очень и очень, опишу основные процедуры и функции которые упрощают и ускоряют мне работу.
Вот мои глобальные процедуры
//Простой возврат
Функция RegExp(Знач тСтрока,Паттерн, MultiLine = Истина, Global = Истина, IgnoreCase = Истина) Экспорт //Возвращает первое вхождение
 RegExp = Новый COMОбъект("VBScript.RegExp");
 тСтрока = Строка(тСтрока);
 RegExp.MultiLine = MultiLine; // истина — текст многострочный, ложь — одна строка 
 RegExp.Global = Global; // истина — поиск по всей строке, ложь — до первого совпадения 
 RegExp.IgnoreCase = IgnoreCase; // истина — игнорировать регистр строки при поиске  
 RegExp.Pattern = Паттерн;
 Matches=RegExp.Execute(Строка(тСтрока));
 Если RegExp.Test(тСтрока) тогда
  Возврат Matches.Item(0).SubMatches.Item(0);
 КонецЕсли;
 Возврат Неопределено;
КонецФункции

//Возврат в массив
Функция RegExpМассив(Строка,Паттерн, MultiLine = Истина, Global = Истина, IgnoreCase = Истина) Экспорт 
 RegExp = Новый COMОбъект("VBScript.RegExp");
 
 RegExp.MultiLine = MultiLine; // истина — текст многострочный, ложь — одна строка 
 RegExp.Global = Global; // истина — поиск по всей строке, ложь — до первого совпадения 
 RegExp.IgnoreCase = IgnoreCase; // истина — игнорировать регистр строки при поиске  
 RegExp.Pattern = Паттерн;
 Matches=RegExp.Execute(Строка);
 возМассив = Новый Массив;
 Если RegExp.Test(Строка) тогда
  Для н=0 по Matches.Count-1 Цикл 
   Для х=0 по Matches.Item(н).SubMatches.Count-1 Цикл
    возМассив.Добавить(Matches.Item(н).SubMatches.Item(х));
   КонецЦикла;
  КонецЦикла;
  Возврат возМассив
 КонецЕсли;
 Возврат возМассив;
КонецФункции

//Возврат в таблицу значений
Функция RegExpТаблицаЗначений(Строка,Паттерн, MultiLine = Истина, Global = Истина, IgnoreCase = Истина, КвоКолонок=0) Экспорт
 RegExp = Новый COMОбъект("VBScript.RegExp");
 Тбл = Новый ТаблицаЗначений;
 Если КвоКолонок=0 тогда
  КвоКолонок = СтрЧислоВхождений(Паттерн,"(");
 КонецЕсли;
 Для х=1 по КвоКолонок Цикл
  Тбл.Колонки.Добавить("К"+х);
 КонецЦикла;
 RegExp.MultiLine = MultiLine; // истина — текст многострочный, ложь — одна строка 
 RegExp.Global = Global; // истина — поиск по всей строке, ложь — до первого совпадения 
 RegExp.IgnoreCase = IgnoreCase; // истина — игнорировать регистр строки при поиске  
 RegExp.Pattern = Паттерн;
 Matches=RegExp.Execute(Строка);
 //возМассив = Новый Массив;
 Если RegExp.Test(Строка) тогда
  Для н=0 по Matches.Count-1 Цикл 
   НоваяСтрока = Тбл.Добавить();
   Для х=0 по Matches.Item(н).SubMatches.Count-1 Цикл
    //возМассив.Добавить(Matches.Item(н).SubMatches.Item(х));
    НоваяСтрока["К"+(х+1)]=Matches.Item(н).SubMatches.Item(х);
   КонецЦикла;
  КонецЦикла;
  Возврат Тбл
 КонецЕсли;
 Возврат Тбл;
КонецФункции

//Замена
Функция RegExpRepalce(Pattern, НачальнаяСтрока,ЗаменяемаяСтрока) Экспорт
 
 RegExp = Новый COMОбъект("VBScript.RegExp");
 //СтруктураФайлов = Новый СписокЗначений;
 RegExp.MultiLine = Истина; // истина — текст многострочный, ложь — одна строка 
 RegExp.Global = Истина; // истина — поиск по всей строке, ложь — до первого совпадения 
 RegExp.IgnoreCase = Истина; // истина — игнорировать регистр строки при поиске  
 RegExp.Pattern = Pattern; 
 ВозвращаемаяСтрока = RegExp.Replace(НачальнаяСтрока,ЗаменяемаяСтрока);
 
 //Matches=RegExp.Execute(НачальнаяСтрока);
 //Если RegExp.Test(НачальнаяСтрока) тогда
 // ВозвращаемаяСтрока = Matches.Item(0).SubMatches.Item(0)+Matches.Item(0).SubMatches.Item(1)+HTMLподпись+Matches.Item(0).SubMatches.Item(2);
 // Возврат СтрЗаменить(ВозвращаемаяСтрока,"<%br%>",Символы.ПС);
 //КонецЕсли;
 
 Возврат ВозвращаемаяСтрока;
КонецФункции

//Проверка
Функция RegExpTest(Строка,Паттерн, MultiLine = Истина, Global = Истина, IgnoreCase = Истина) Экспорт 
 RegExp = Новый COMОбъект("VBScript.RegExp");
 
 RegExp.MultiLine = MultiLine; // истина — текст многострочный, ложь — одна строка 
 RegExp.Global = Global; // истина — поиск по всей строке, ложь — до первого совпадения 
 RegExp.IgnoreCase = IgnoreCase; // истина — игнорировать регистр строки при поиске  
 RegExp.Pattern = Паттерн;
 //Matches=RegExp.Execute(Строка); 
 Возврат RegExp.Test(Строка);
 
КонецФункции


Загрузка банковских выписок, на примере банка "Аваль"

Возникла ситуация при которой необходимо было загрузить и обработать выписка банка Аваль. Задача была немного специфичная, но за нее платят - значит делаем.
С первым с чем столкнулся - это выгрузка, получил ее в формате csv, в общем текстовый формат. Интересовала меня распарсивание одной строки

Дата транзакції,"Дата списання","Номер картки ","Тип транзакції","Деталі транзакції","Вхідний залишок","Сума у валюті рахунку","Сума в валюті транзакції","Валюта транзакції","Вихідний залишок"

Для упрощения гемороя в работе со строками, давно использую regex, чего и всем рекомендую. Также рекомендую для тестировани и настройки работы пользоваться сайтом, ну и большое THANKS ребятам которые его сделали.
В общем первое создаем внешнюю обработку, а в ней форму
В форме кроме реквизитов добавляем 2 команды "КомандаЗагрузить" и "СоздатьДокументы", после этого пишем следующий код:


&НаКлиенте
Процедура КомандаЗагрузить(Команда)
 Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
 Диалог.Заголовок = "Выбирете файлы для загрузки в 1С";
 Диалог.Фильтр = "CSV (*.csv)|*.csv|Все файлы|*.*";
 Диалог.МножественныйВыбор=Ложь;
 Диалог.ПроверятьСуществованиеФайла = Истина;
 Если Диалог.Выбрать() Тогда
      ВыбранногоФайла = Диалог.ВыбранныеФайлы[0];
   ТФайл = Новый Файл(ВыбранногоФайла);
   Если ТФайл.Существует() тогда    
    Адрес = ПоместитьВоВременноеХранилище(Новый ДвоичныеДанные(ВыбранногоФайла));
    ЗагрузитьКассы(Адрес);
   Иначе
    Сообщение = Новый СообщениеПользователю();
       Сообщение.Текст = "Не удалось найти файл:"+ВыбранногоФайла;       
       Сообщение.Сообщить();
   КонецЕсли;  
 КонецЕсли;
КонецПроцедуры

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
 НаДату = ТекущаяДата();
 Касса = Справочники.Кассы.НайтиПоНаименованию("Аваль");
 Контргаент = Константы.НеОпределенКонтрагент.Получить();
КонецПроцедуры


Процедура ЗагрузитьКассы(Адрес)
 ВремФайл = ПолучитьИмяВременногоФайла("csv");
 ДанныеХранилища = ПолучитьИзВременногоХранилища(Адрес);
 ДанныеХранилища.Записать(ВремФайл);
 
 ЧФ = Новый ЧтениеТекста(ВремФайл);
 БуфферСтрок = ЧФ.Прочитать();
 ЧФ.Закрыть();
 
 ВремТБЛ = RegExpТаблицаЗначений(БуфферСтрок,"""(\d{2}.\d{2}.\d{4})"",""\d{2}.\d{2}.\d{4}"","".*"","".*"",""Готівкове поповнення.*"",""[\d\s\.]*"",""([\d\s\.]*)"",""[\d\s\.]*"",""UAH"",""[\d\s\.]*""");
 ТаблицаСумм.Очистить();
 Нумерация = 1;
 Для Каждого СтрокаВремТбл из ВремТБЛ Цикл
  НС = ТаблицаСумм.Добавить();
  НС.Номер = Нумерация;
  Нумерация = Нумерация+1;
  НС.Загружать = Истина;
  МассивДаты = МастерПроцедурыСервера.RegExpМассив(СтрокаВремТбл.К1,"(\d{2}).(\d{2}).(\d{4})");
  Если МассивДаты.Количество()=3 тогда
   НС.Дата = Дата(МассивДаты[2],МассивДаты[1],МассивДаты[0]);
  Иначе
   НС.Дата = НаДату;
  КонецЕсли;
  НС.Сумма = Число(СтрЗаменить(СтрокаВремТбл.К2," ",""));
  НС.Контрагент = Контргаент;
 КонецЦикла;
 Элементы.ТаблицаСумм.Подвал=Истина;
 Элементы.ТаблицаСуммСумма.ТекстПодвала = ТаблицаСумм.Итог("Сумма");
 //Элементы.ТаблицаСуммСумма.ПутьКДаннымПодвала
КонецПроцедуры

Функция RegExpТаблицаЗначений(Строка,Паттерн, MultiLine = Истина, Global = Истина, IgnoreCase = Истина) Экспорт //Возвращает первое вхождение
 RegExp = Новый COMОбъект("VBScript.RegExp");
 Тбл = Новый ТаблицаЗначений;
 КвоКолонок = СтрЧислоВхождений(Паттерн,"(");
 Для х=1 по КвоКолонок Цикл
  Тбл.Колонки.Добавить("К"+х);
 КонецЦикла;
 RegExp.MultiLine = MultiLine; // истина — текст многострочный, ложь — одна строка 
 RegExp.Global = Global; // истина — поиск по всей строке, ложь — до первого совпадения 
 RegExp.IgnoreCase = IgnoreCase; // истина — игнорировать регистр строки при поиске  
 RegExp.Pattern = Паттерн;
 Matches=RegExp.Execute(Строка);
 //возМассив = Новый Массив;
 Если RegExp.Test(Строка) тогда
  Для н=0 по Matches.Count-1 Цикл 
   НоваяСтрока = Тбл.Добавить();
   Для х=0 по Matches.Item(н).SubMatches.Count-1 Цикл
    //возМассив.Добавить(Matches.Item(н).SubMatches.Item(х));
    НоваяСтрока["К"+(х+1)]=Matches.Item(н).SubMatches.Item(х);
   КонецЦикла;
  КонецЦикла;
  Возврат Тбл
 КонецЕсли;
 Возврат Тбл;
КонецФункции

&НаКлиенте
Процедура ТаблицаСуммПослеУдаления(Элемент)
 УстановитьНомераСтрок();
КонецПроцедуры

&НаКлиенте 
Процедура УстановитьНомераСтрок()
 Для Каждого СтроТовары из ТаблицаСумм Цикл
  СтроТовары.НомерСтроки = ТаблицаСумм.Индекс(СтроТовары)+1;
 КонецЦикла;
КонецПроцедуры


&НаКлиенте
Процедура ТаблицаСуммПриИзменении(Элемент)
 УстановитьНомераСтрок();
КонецПроцедуры


&НаКлиенте
Процедура СоздатьДокументы(Команда)
 СоздатьДокументыНаСервере();
КонецПроцедуры


&НаСервере
Процедура СоздатьДокументыНаСервере()
 Для Каждого стрТаблицаСумм из ТаблицаСумм Цикл
  Если стрТаблицаСумм.Загружать и не ЗначениеЗаполнено(стрТаблицаСумм.Документ) тогда
   ДокОбъект = Документы.ПриходныйКассовыйОрдер.СоздатьДокумент();
   ДокОбъект.Дата = стрТаблицаСумм.Дата;
   ДокОбъект.УстановитьНовыйНомер();
   ДокОбъект.ХозяйственнаяОперация = Перечисления.ХозяйственныеОперации.ПоступлениеОплатыОтКлиента;
   ДокОбъект.Контрагент = Контргаент;
   ДокОбъект.Касса = Касса;
   ДокОбъект.Валюта = Касса.ВалютаДенежныхСредств;
   ДокОбъект.Кассир = ПараметрыСеанса.ТекущийПользователь;
   ДокОбъект.Организация = Константы.ОсновнаяОрганизация.Получить();
   ДокОбъект.СуммаДокумента = стрТаблицаСумм.Сумма;
   ДокОбъект.СтатьяДвиженияДенежныхСредств = Справочники.СтатьиДвиженияДенежныхСредств.ПоступлениеОплатыОтКлиента;
   ВремТабл = Мастер.РасшифровкаПлатежаЗаполнитьПоОстаткам(ДокОбъект);
   Если НЕ ВремТабл = неопределено тогда
    ДокОбъект.РасшифровкаПлатежа.Загрузить(ВремТабл);
   КонецЕсли;

   ДокОбъект.Записать(РежимЗаписиДокумента.Проведение);
   стрТаблицаСумм.Документ = ДокОбъект.Ссылка;
  КонецЕсли;
 КонецЦикла;
КонецПроцедуры


После этого не забываем, что данную обработку подключим внешней обработкой к УТ11 и добавляем в модуле следующие строки:

Функция СведенияОВнешнейОбработке() Экспорт
 
 Структура = Новый Структура;
 Структура.Вставить("Вид",             "ДополнительнаяОбработка"); //Перечисления.ВидыДополнительныхОтчетовИОбработок.ДополнительнаяОбработка
 Структура.Вставить("Наименование",    "Создание кассовых поступлений");
 Структура.Вставить("Версия",          "1.01");
 Структура.Вставить("БезопасныйРежим", Ложь);
 Структура.Вставить("Информация",      "Создание кассовых поступлений");
 
 Команды = Новый ТаблицаЗначений;
 Команды.Колонки.Добавить("Идентификатор");
 Команды.Колонки.Добавить("Представление");
 Команды.Колонки.Добавить("Модификатор");
 Команды.Колонки.Добавить("ПоказыватьОповещение");
 Команды.Колонки.Добавить("Использование");
 
 
 НоваяСтрока = Команды.Добавить();
 НоваяСтрока.Идентификатор = "1";
 НоваяСтрока.Представление = "Создание кассовых поступлений";
 НоваяСтрока.ПоказыватьОповещение = Истина;
 НоваяСтрока.Использование = "ОткрытиеФормы";
 
 
 Структура.Вставить("Команды", Команды);
 
 
 Возврат Структура;
 
КонецФункции



вот в принципе и все, успехов в работе.