Friday, September 9, 2011

Расшифровка МТС звонков спомощью C# и regex.

В связи с анализом разговоров МТС необходимо было написать систему расшифровки звонком МТС, так как 1С очень медлено работает с текстовыми файлами пришлось решать эту проблему с помощью C# и regex(спасибо Linux).
Основная схема состоит в формирование данных для скула, с последующей ставкой (bulk load). Весь анализ выполнял уже в 1С 8.2.14.532



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Compression;
using System.IO;
using Ionic.Zip;
using System.Text.RegularExpressions;
using System.Data.SqlClient;



namespace WorkWithMTS
{


class Program
    {

        private static void DeleteData(string connectionString, string Table,string SelectDate)
        {
            string queryString =
                "Delete from " + Table + "  where [ReportDate]=Cast('" + SelectDate + "T00:00:00' as datetime)";
            using (SqlConnection connection = new SqlConnection(
                       connectionString))
            {
                SqlCommand command = new SqlCommand(
                    queryString, connection);
                connection.Open();
                command.CommandTimeout = 1000;
                command.ExecuteNonQuery();
                
            }
        }

        private static void UpdateDateCall(string connectionString, string Table)
        {
            string queryString =
                "UPDATE " + Table + " SET [DateCall]=[CallDate]+[CallTime]";
            using (SqlConnection connection = new SqlConnection(
                       connectionString))
            {
                SqlCommand command = new SqlCommand(
                    queryString, connection);
                connection.Open();
                command.CommandTimeout = 1000;
                command.ExecuteNonQuery();

            }
        }


        private static void BulkInsert(string connectionString, string Table, string filename)
        {
            string queryString =
                @"BULK INSERT " + Table + @"
                    FROM '"+filename+@"'
                    WITH 
                    (
                        CODEPAGE='1251',
                        FIELDTERMINATOR =',',
                        ROWTERMINATOR ='\n'
                    )";
            using (SqlConnection connection = new SqlConnection(
                       connectionString))
            {
                
                SqlCommand command = new SqlCommand(
                    queryString, connection);
                connection.Open();
                command.CommandTimeout = 1000;
                command.ExecuteNonQuery();
                 
            }
        }



static void Main(string[] args)
        {
            string dir = null;
            string cs = null;
            //string dir = @"g:\agromars\MTS\01\";
            if (args.Count() != 0)
            {
                dir = args[0];
            }

            if ((dir==null) || (dir.Length<2))
            {
                dir = Directory.GetCurrentDirectory()+@"\";
            }


if (!System.IO.Directory.Exists(dir))
            {
                Console.WriteLine("Папка не обнаружена!\n");
                System.Console.ReadKey();
                return;
            }


            string[] filePaths = Directory.GetFiles(dir, "*.csv");

            var sortfilePaths = from s in filePaths
                                orderby s
                                select s;

            if (filePaths.Count() == 0)
            {
                Console.WriteLine("Файлы для обработки не обнаружены!!!");
                System.Console.ReadKey();
                return;
            }
            //cs = "Data Source=.;Initial Catalog=Phone_MTS;User Id=userMTS;Password=userMTS;";
            //DeleteData(cs, "[Phone_MTS].[dbo].[Services]", "2011-01-31");

            //delete tmp file
            string[] filestemp = Directory.GetFiles(dir, "*.tmp");
            foreach (string filetemp in filestemp)
            {
                FileInfo filestodel = new FileInfo(filetemp);
                filestodel.Delete();
            }


FileStream fin;
            FileStream foutH;
            FileStream foutHPacket;
            FileStream foutS;
            FileStream foutSMsg;
            FileStream foutSInet;
            FileStream foutSOth;
            FileStream foutTrash = new FileStream(dir +  "Trash.tmp", FileMode.Append);;

            StreamWriter fstr_outH = null;
            StreamWriter fstr_outHPacket = null;
            StreamWriter fstr_outS = null;
            StreamWriter fstr_outSMsg = null;
            StreamWriter fstr_outSInet = null;
            StreamWriter fstr_outSOth = null;
            StreamWriter fstr_outTrash = new StreamWriter(foutTrash);

            string str;
            string Contract = null, PhoneNumber = "", NameDate = "", NameDateS=null, ORah=null;


            Regex rstr = new Regex(@"^.*,.*,.*,.*,(?<valuephone>.*),\d{4}\-\d{2}\-\d{2},\s*\d{2}:\d{2}:\d{2},\d{2}:\d{2}:\d{2},.*,[0-9-\.]*$"); //Ищем строки документа звонки
            Regex rstrOth = new Regex(@"^.*,.*,.*,.*,.*,\d{4}\-\d{2}\-\d{2},\s*\d{2}:\d{2}:\d{2},.*,.*,[0-9-\.]*$"); //Ищем строки документа остальные
            Regex rstrMsg = new Regex(@"^.*,.*,.*,.*,.*,\d{4}\-\d{2}\-\d{2},\s*\d{2}:\d{2}:\d{2},.*Msg,.*,[0-9-\.]*$"); //Ищем строки документа Msg
            Regex rstrInet = new Regex(@"^.*,.*,.*,.*,.*,\d{4}\-\d{2}\-\d{2},\s*\d{2}:\d{2}:\d{2},\s*[0-9\.]*\s*(b|K|M|Kb|Mb),.*,[0-9-\.]*$"); //Ищем строки документа Inet

            Regex rH = new Regex(@"^(?<value>.*),.*,.*,[0-9-\.]*$"); //Ищем шапки документа


foreach (string filepath in sortfilePaths)
            {
                
                try
                {
                    fin = new FileStream(filepath, FileMode.Open); // чтение файла
                }
                catch (FileNotFoundException ex)
                {

                    Console.WriteLine("Ошибка:" + ex.Message);
                    System.Console.ReadKey();
                    return;
                }

                StreamReader fstr_in = new StreamReader(fin, Encoding.Default);


while ((str = fstr_in.ReadLine()) != null)
                {

                    //ищем дату
                    Regex r = new Regex(@"Номер рахунку\s*\d*\s*від\s*(?<valuedate>[0-9]{1,2}[.][0-9]{1,2}[.][0-9]{4})");
                    // Find a single match in the string.
                    Match m = r.Match(str);
                    if ((m.Success) && (NameDate != m.Groups["valuedate"].Value))
                    {
                        NameDate = m.Groups["valuedate"].Value;
                        NameDateS = Convert.ToDateTime(NameDate).ToString("yyyy-MM-dd");
                        Contract = null;
                        if (fstr_outS == null)
                        {
                            //if (fstr_outS != null)
                            //{
                            //    fstr_outS.Close();
                            //    fstr_outSMsg.Close();
                            //    fstr_outSInet.Close();
                            //    fstr_outSOth.Close();                                
                            //}
                            try
                            {
                                foutS = new FileStream(dir + NameDate + "_Str.tmp", FileMode.Append);                                
                                foutSMsg = new FileStream(dir + NameDate + "_StrMsg.tmp", FileMode.Append);
                                foutSInet = new FileStream(dir + NameDate + "_StrInet.tmp", FileMode.Append);
                                foutSOth = new FileStream(dir + NameDate + "_StrOth.tmp", FileMode.Append);
                            }
                            catch (IOException ex)
                            {
                                Console.WriteLine("Ошибка:" + ex.Message);
                                System.Console.ReadKey();
                                return;
                            }
                            fstr_outS = new StreamWriter(foutS, Encoding.GetEncoding(1251));
                            fstr_outSMsg = new StreamWriter(foutSMsg, Encoding.GetEncoding(1251));
                            fstr_outSInet = new StreamWriter(foutSInet, Encoding.GetEncoding(1251));
                            fstr_outSOth = new StreamWriter(foutSOth, Encoding.GetEncoding(1251)); 
                        }

                        if (fstr_outH == null)
                        {
                            try
                            {
                                foutH = new FileStream(dir + NameDate + "_Head.tmp", FileMode.Append);
                                foutHPacket = new FileStream(dir + NameDate + "_HeadPacket.tmp", FileMode.Append);
                                
                            }
                            catch (IOException ex)
                            {
                                Console.WriteLine("Ошибка:" + ex.Message);
                                System.Console.ReadKey();
                                return;
                            }
                            fstr_outH = new StreamWriter(foutH,Encoding.GetEncoding(1251));
                            fstr_outHPacket = new StreamWriter(foutHPacket, Encoding.GetEncoding(1251));
                        }

                    }



//Если контракты
                    Regex rORah = new Regex(@"Особовий рахунок:\s*(?<value>\w.*)");
                    // Find a single match in the string.
                    Match mORah = rORah.Match(str);
                    if (mORah.Success)
                    {
                        ORah = mORah.Groups["value"].Value;                      
                        //Console.Write(str);
                    }


                    //Если контракты
                    Regex r1 = new Regex(@"Контракт\s*№\s*(?<value>\d*)");
                    // Find a single match in the string.
                    Match m1 = r1.Match(str);
                    if (m1.Success)
                    {
                        Contract = m1.Groups["value"].Value;
                       Regex rch = new Regex(@"Контракт\s*№\s*(?<value>\d*)\s*Номер телефону:\s*(?<phonevalue>\d*)");
                       Match mch = rch.Match(str);
                       if (mch.Success)
                       {
                           PhoneNumber = mch.Groups["phonevalue"].Value;
                       }
                       else
                       {
                           PhoneNumber = "";
                       }
                        
                        Console.WriteLine(str);                                                
                    }
                    int strCount = str.ToCharArray().Where((x) => x == ',').Count();
                    //Вычисляем пакеты данных //Ціновий пакет:
                    if ((Contract != null) && (fstr_outH != null))
                    {
                        Regex rPacket = new Regex(@"Ціновий пакет:\s*(?<value>\w.*)");
                        Match mPacket = rPacket.Match(str);
                        if (mPacket.Success)
                        {
                            fstr_outHPacket.WriteLine(ORah + "," + Contract + "," + PhoneNumber + "," + NameDateS + "," + mPacket.Groups[1].Value.Trim());
                        }
                        
                    }

                    if ((Contract != null) && (fstr_outH != null) && ((strCount >= 3) && (strCount<9)))
                    {
                        try
                        {
                            
                            Match mH = rH.Match(str);
                            if (mH.Success)
                            {
                                string strService = mH.Groups["value"].Value.Replace(",", ".");
                                //str = Regex.Replace(str, mH.Groups["value"].Value, strService);
                                str = str.Replace(mH.Groups["value"].Value, strService);

                                fstr_outH.WriteLine(ORah + "," + Contract + "," + PhoneNumber + "," + NameDateS + "," + str);
                                continue;
                            }
                            Regex rHOther = new Regex(@"^"".*"",.*,.*,[0-9-\.]*$"); //Ищем шапки документа, с неправильной структурой
                            Match mHOther = rHOther.Match(str);
                            if (mHOther.Success)
                            {
                                fstr_outH.WriteLine(ORah + "," + Contract + "," + PhoneNumber + "," + NameDateS + "," + str);
                                continue;
                            }

                            Console.WriteLine("Внимание:" + ORah + "," + Contract + "," + PhoneNumber + "," + NameDateS + "," + str);

                        }
                        catch (IOException ex)
                        {
                            Console.WriteLine("Ошибка:" + ex.Message);
                            System.Console.ReadKey();
                            return;
                        }
                    }


                    if ((Contract != null) && (fstr_outS != null) && (strCount == 9))
                    {
                        // конвертим дату для bulk
                        Regex rTDate = new Regex(@"([\d]{2})\.([\d]{2})\.([\d]{4})");
                        str = rTDate.Replace(str, @"$3-$2-$1");
 

                        try
                        {
                             Match mstrMsg = rstrMsg.Match(str);
                            if (mstrMsg.Success) 
                            {
                                // Убираем Msg
                                Regex rTMsg = new Regex(@"([\d]*)\s*Msg");
                                str = rTMsg.Replace(str, @"$1");
                                fstr_outSMsg.WriteLine(ORah + "," + Contract + "," + PhoneNumber + "," + NameDateS + "," + str + ",");
                                continue;
                            }
                            Match mstrInet = rstrInet.Match(str); 
                            if (mstrInet.Success)
                            {
                                // Пересчитываем в байты
                                //\s*(?<valuestring>\w*)
                                Regex rT1 = new Regex(@"(?<valuenumber>[0-9\.]+)\s+(?<valuestring>b|Kb|Mb|M|K)");
                                Match mrT1 = rT1.Match(str);
                                string strbyte = null;
                                if (mrT1.Success)
                                {
                                    decimal tbyte = Convert.ToDecimal(mrT1.Groups["valuenumber"].Value.Replace(".",","));
                                    if (mrT1.Groups[2].Value == "b")
                                        strbyte = tbyte.ToString();
                                    else if ((mrT1.Groups[2].Value == "Kb") || (mrT1.Groups[2].Value == "K"))
                                        strbyte = Convert.ToInt64(tbyte * 1024).ToString();
                                    else if ((mrT1.Groups[2].Value == "Mb") || (mrT1.Groups[2].Value == "M"))
                                        strbyte = Convert.ToInt64(tbyte * 1024 * 1024).ToString();
                                    else if ((mrT1.Groups[2].Value == "Gb") || (mrT1.Groups[2].Value == "G"))
                                        strbyte = Convert.ToInt64(tbyte * 1024 * 1024 * 1024).ToString();
                                    else if (mrT1.Groups[2].Value != "")
                                        Console.WriteLine("Ошибка:" + Contract + "," + PhoneNumber + "," + NameDateS + "," + str);

                                    Regex rT2 = new Regex(@"(?<valuenumber>[0-9\.]+)\s+(?<valuestring>b|Kb|Mb|M|K)");
                                    str = rT2.Replace(str, strbyte);
                                }
                                fstr_outSInet.WriteLine(ORah + "," + Contract + "," + PhoneNumber + "," + NameDateS + "," + str + ",");
                                continue;
                            }
                            Match mstr = rstr.Match(str);
                            if (mstr.Success)
                            {
                                string direction = "";//mstr.Groups[1].Value.ToString();
                                Regex rD = new Regex(@"\.*(?<valuenumber>[0-9A-Za-z]*)(?=[0-9A-Za-z]{7,})"); // \.*([0-9A-Za-z]*)(?=[0-9A-Za-z]{7,}) // (?<valuenumber>.*)(?=\d{7,})
                                Match mrD = rD.Match(str);
                                if (mrD.Success)
                                {
                                    direction = mrD.Groups[1].Value.Trim();
                                    if ((direction.Length > 3) && ((direction.IndexOf("38", 0) != -1) || (direction.IndexOf("15", 0) != -1) || (direction.StartsWith("0"))))
                                    {
                                        int MaxLength = Math.Min(direction.Length, 6);
                                        direction = direction.Substring(direction.Length - MaxLength, MaxLength).Trim();
                                        direction = direction.Substring(direction.Length - 3, 3);
                                    }
                                    else if (direction.Length == 2)
                                        direction = "0" + direction;
                                    else if ((direction.Length == 4) && direction.StartsWith("8"))
                                    {
                                        
                                        direction = direction.Substring(1, 3);
                                    }
                                    else if (direction.Length > 3)
                                    {
                                        direction = "";
                                    }
                                }
                                //direction=direction.Substring(direction.Length-10, 10).Substring(0,3);


                                // Пересчитываем в секунды
                                //\s*(?<valuestring>\w*)

                                int sec = 0;
                                Regex rTS = new Regex(@"\d{4}\-\d{2}\-\d{2},.*\d{2}:\d{2}:\d{2},.*(\d{2}):(\d{2}):(\d{2}),");
                                Match mrTS = rTS.Match(str);
                                
                                if (mrTS.Success)
                                {
                                    int tsec = Convert.ToInt16(mrTS.Groups[3].Value);
                                    int tmin = Convert.ToInt16(mrTS.Groups[2].Value);
                                    int thour = Convert.ToInt16(mrTS.Groups[1].Value);

                                    sec = thour * 60 * 60 + tmin * 60 + tsec;

                                    //Regex rT2S = new Regex(@"\d{4}\.\d{2}\.\d{2},.*\d{2}:\d{2}:\d{2},.*(\d{2}):(\d{2}):(\d{2}),");
                                    //str = rT2S.Replace(str, strbyte);
                                }

                                string strToPhone = "";
                                Regex rPhone = new Regex(@"\d*(?=(\d{9}))");
                                Match mrPhone = rPhone.Match(str);

                                if (mrPhone.Success)
                                {

                                    strToPhone = mrPhone.Groups[1].Value;
                                }


                                fstr_outS.WriteLine(ORah + "," + Contract + "," + PhoneNumber + "," + NameDateS + "," + direction + "," + strToPhone + "," + sec + "," + str + ",");
                                continue;
                            }
                            Match mstrOth = rstrOth.Match(str);
                            if (mstrOth.Success)
                            {
                                fstr_outSOth.WriteLine(ORah + "," + Contract + "," + PhoneNumber + "," + NameDateS + "," + str + ",");
                                continue;
                            }
                            Console.WriteLine("Внимание:" + ORah + "," + Contract + "," + PhoneNumber + "," + NameDateS + "," + str);
                            
                        }
                        catch (IOException ex)
                        {
                            Console.WriteLine("Ошибка:"+ex.Message);
                            System.Console.ReadKey();
                            return;
                        }
                    }
                    fstr_outTrash.WriteLine(str);

                }
                fstr_in.Close();
                
            }


fstr_outS.Close();
            fstr_outSMsg.Close();           
            fstr_outSInet.Close();
            fstr_outSOth.Close();
            fstr_outH.Close();
            fstr_outHPacket.Close();
            fstr_outTrash.Close();



            Console.WriteLine("Загрузка в SQL");
            
            if (args.Count() > 0)
            {
                cs = args[1];
            }
            if ((cs == null) || (cs.Length == 0))
            {
                cs = "Data Source=.;Initial Catalog=Phone_MTS;User Id=userMTS;Password=userMTS;";
            }
            DeleteData(cs, "[Phone_MTS].[dbo].[Services]", NameDateS);
            DeleteData(cs, "[Phone_MTS].[dbo].[Packages]", NameDateS);
            DeleteData(cs, "[Phone_MTS].[dbo].[ExplanationCalls]", NameDateS);
            DeleteData(cs, "[Phone_MTS].[dbo].[ExplanationInet]", NameDateS);
            DeleteData(cs, "[Phone_MTS].[dbo].[ExplanationMsg]", NameDateS);
            DeleteData(cs, "[Phone_MTS].[dbo].[ExplanationOther]", NameDateS);


            BulkInsert(cs, "[Phone_MTS].[dbo].[Services]", dir + NameDate + "_Head.tmp");
            BulkInsert(cs, "[Phone_MTS].[dbo].[Packages]", dir + NameDate + "_HeadPacket.tmp");
            BulkInsert(cs, "[Phone_MTS].[dbo].[ExplanationCalls]", dir + NameDate + "_Str.tmp");
            BulkInsert(cs, "[Phone_MTS].[dbo].[ExplanationInet]", dir + NameDate + "_StrInet.tmp");
            BulkInsert(cs, "[Phone_MTS].[dbo].[ExplanationMsg]", dir + NameDate + "_StrMsg.tmp");
            BulkInsert(cs, "[Phone_MTS].[dbo].[ExplanationOther]", dir + NameDate + "_StrOth.tmp");

            UpdateDateCall(cs, "[Phone_MTS].[dbo].[ExplanationCalls]");
            UpdateDateCall(cs, "[Phone_MTS].[dbo].[ExplanationInet]");
            UpdateDateCall(cs, "[Phone_MTS].[dbo].[ExplanationMsg]");
            UpdateDateCall(cs, "[Phone_MTS].[dbo].[ExplanationOther]");

            Console.WriteLine("Выполнено! Press any key!");
            System.Console.ReadKey();
        }
    }

}






После формируем таблицы в скуле
Таблица сервисов


CREATE TABLE [dbo].[Services](
    [Rahunok] [nchar](20) NOT NULL,
    [Contract] [nchar](10) NOT NULL,
    [Phone] [nchar](9) NULL,
    [ReportDate] [datetime]  NOT NULL,
    [NameServices] [nvarchar](250) NULL,    
    [Sum1] [decimal](12, 2) NULL,
    [Sum2] [decimal](12, 2) NULL,
    [Sum3] [decimal](12, 2) NULL        
) ON [PRIMARY]

GO

Таблица пакетов


CREATE TABLE [dbo].[Packages](
    [Rahunok] [nchar](20) NOT NULL,
    [Contract] [nchar](10) NOT NULL,
    [Phone] [nchar](9) NULL,
    [ReportDate] [datetime] NOT NULL,
    [NamePackege] [nvarchar](250) NULL
    
) ON [PRIMARY]

GO

Таблица операторов



CREATE TABLE [dbo].[Operators](
    [OperatorName] [nvarchar](50) NOT NULL,
    [Direction] [nchar](3) NOT NULL
) ON [PRIMARY]

GO

В которую вносим следующие данные
OperatorName Direction
Golden Telecom 039
life:) 063
life:) 093
PEOPLEnet 092
Utel 091
Интертелеком 094
Киевстар 067
Киевстар 068
Киевстар 096
Киевстар 097
Киевстар 098
МТС 050
МТС 066
МТС 095
МТС 099

Далее таблица по расшифровке звонков


CREATE TABLE [dbo].[ExplanationCalls](
    [Rahunok] [nchar](20) NOT NULL,
    [Contract] [nchar](10) NOT NULL,
    [Phone] [nchar](9) NULL,
    [ReportDate] [datetime] NULL,
    [Direction] [nchar](3) NULL,
    [ToPhone] [nchar](9) NULL,
    [Duration] [bigint] NULL,
    [Unknown1] [nvarchar](50) NULL,
    [Unknown2] [nvarchar](50) NULL,
    [Type] [nvarchar](18) NULL,
    [Info] [nvarchar](20) NULL,
    [Call] [nvarchar](15) NULL,
    [CallDate] [datetime] NULL,
    [CallTime] [time](7) NULL,
    [CallDuration] [time](7) NULL,
    [Unknown3] [nvarchar](50) NULL,
    [Cost] [decimal](12, 2) NULL,    
    [DateCall] [datetime] NULL -- Для формирования точной даты звонка необходим для 1с, что бы не заниматься лишней обработкой
    
) ON [PRIMARY]

GO

Таблица расшифровки интернет трафика


CREATE TABLE [dbo].[ExplanationInet](
    [Rahunok] [nchar](20) NOT NULL,
    [Contract] [nchar](10) NOT NULL,
    [Phone] [nchar](9) NULL,
    [ReportDate] [datetime] NULL,
    [Unknown1] [nvarchar](50) NULL,
    [Unknown2] [nvarchar](50) NULL,
    [Type] [nvarchar](18) NULL,
    [Info] [nvarchar](20) NULL,
    [Call] [nvarchar](15) NULL,
    [CallDate] [datetime] NULL,
    [CallTime] [time](7) NULL,
    [CallDuration] [bigint] NULL,
    [Unknown3] [nvarchar](50) NULL,
    [Cost] [decimal](12, 2) NULL,
    [DateCall] [datetime] NULL -- Для формирования точной даты звонка необходим для 1с, что бы не заниматься лишней обработкой
) ON [PRIMARY]

GO

Таблица смс


CREATE TABLE [dbo].[ExplanationMsg](
    [Rahunok] [nchar](20) NOT NULL,
    [Contract] [nchar](10) NOT NULL,
    [Phone] [nchar](9) NULL,
    [ReportDate] [datetime] NULL,
    [Unknown1] [nvarchar](50) NULL,
    [Unknown2] [nvarchar](50) NULL,
    [Type] [nvarchar](18) NULL,
    [Info] [nvarchar](20) NULL,
    [Call] [nvarchar](15) NULL,
    [CallDate] [datetime] NULL,
    [CallTime] [time](7) NULL,
    [CallDuration] [bigint] NULL,
    [Unknown3] [nvarchar](50) NULL,
    [Cost] [decimal](12, 2) NULL,
    [DateCall] [datetime] NULL -- Для формирования точной даты звонка необходим для 1с, что бы не заниматься лишней обработкой
) ON [PRIMARY]

GO
И последняя таблица со всяким мусором который не расшифровался


CREATE TABLE [dbo].[ExplanationOther](
    [Rahunok] [nchar](20) NOT NULL,
    [Contract] [nchar](10) NOT NULL,
    [Phone] [nchar](9) NULL,
    [ReportDate] [datetime] NULL,
    [Unknown1] [nvarchar](50) NULL,
    [Unknown2] [nvarchar](50) NULL,
    [Type] [nvarchar](18) NULL,
    [Info] [nvarchar](20) NULL,
    [Call] [nvarchar](15) NULL,
    [CallDate] [datetime] NULL,
    [CallTime] [time](7) NULL,
    [CallDuration] [nvarchar](8) NULL,
    [Unknown3] [nvarchar](50) NULL,
    [Cost] [decimal](12, 2) NULL,
    [DateCall] [datetime] NULL
) ON [PRIMARY]

GO

Friday, July 22, 2011

обработка по обмену через xml

Обработку писал в быстром темпе, для одинаковых баз данных, ее задача выбрать объект и все связанные с ним элементы и перенести в другую базу.

Перем СписокДляВыгрузки,СписокОбщий,Запись;

Процедура КнопкаВыполнитьНажатие(Кнопка)
 // Вставить содержимое обработчика.
КонецПроцедуры

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


Функция ОпределитьНаличиеДвиженийПоРегистратору(ДокументСсылка)
 ТекстЗапроса = ""; 
 // для исключения падения для документов, проводящимся более чем по 256 таблицам
 счетчик_таблиц = 0;
 
 МетаданнныеДокумента = ДокументСсылка.Метаданные();
 
 Если МетаданнныеДокумента.Движения.Количество() = 0 Тогда
  Возврат Новый ТаблицаЗначений;
 КонецЕсли;
 
 Для Каждого Движение ИЗ МетаданнныеДокумента.Движения Цикл
  // в запросе получаем имена регистров, по которым есть хотя бы одно движение
  // например,
  // ВЫБРАТЬ Первые 1 «РегистрНакопления.ТоварыНаСкладах»
  // ИЗ РегистрНакопления.ТоварыНаСкладах
  // ГДЕ Регистратор = &Регистратор
  
  // имя регистра приводим к Строка(200), см. ниже
  ТекстЗапроса = ТекстЗапроса + "
  |" + ?(ТекстЗапроса = "", "", "ОБЪЕДИНИТЬ ВСЕ ") + "
  |ВЫБРАТЬ ПЕРВЫЕ 1 ВЫРАЗИТЬ(""" + Движение.ПолноеИмя() 
  +  """ КАК Строка(200)) КАК Имя ИЗ " + Движение.ПолноеИмя() 
  + " ГДЕ Регистратор = &Регистратор";
  
  // если в запрос попадает более 256 таблиц – разбиваем его на две части
  // (вариант документа с проведением по 512 регистрам считаем нежизненным)
  счетчик_таблиц = счетчик_таблиц + 1;
  Если счетчик_таблиц = 256 Тогда
   Прервать;
  КонецЕсли;
  
 КонецЦикла;
 
 Запрос = Новый Запрос(ТекстЗапроса);
 ЗАпрос.УстановитьПараметр("Регистратор", ДокументСсылка);
 // при выгрузке для колонки «Имя» тип устанавливается по самой длинной строке из запроса
 // при втором проходе по таблице новое имя может не «влезть», по этому сразу в запросе
 // приводится к строка(200)
 ТаблицаЗапроса = Запрос.Выполнить().Выгрузить();
 
 // если количество таблиц не превысило 256 – возвращаем таблицу
 Если счетчик_таблиц = МетаданнныеДокумента.Движения.Количество() Тогда
  Возврат ТаблицаЗапроса;   
 КонецЕсли;
 
 // таблиц больше чем 256, делаем доп. запрос и дополняем строки таблицы.
 
 ТекстЗапроса = "";
 Для Каждого Движение ИЗ МетаданнныеДокумента.Движения Цикл
  
  Если счетчик_таблиц > 0 Тогда
   счетчик_таблиц = счетчик_таблиц - 1;
   Продолжить;
  КонецЕсли;
  
  ТекстЗапроса = ТекстЗапроса + "
  |" + ?(ТекстЗапроса = "", "", "ОБЪЕДИНИТЬ ВСЕ ") + "
  |ВЫБРАТЬ ПЕРВЫЕ 1 """ + Движение.ПолноеИмя() +  """ КАК Имя ИЗ " 
  + Движение.ПолноеИмя() + " ГДЕ Регистратор = &Регистратор"; 
  
  
 КонецЦикла;
 Запрос.Текст = ТекстЗапроса;
 Выборка = Запрос.Выполнить().Выбрать();
 Пока Выборка.Следующий() Цикл
  СтрокаТаблицы = ТаблицаЗапроса.Добавить();
  ЗаполнитьЗначенияСвойств(СтрокаТаблицы, Выборка);
 КонецЦикла;
 
 Возврат ТаблицаЗапроса;
 
КонецФункции


Процедура ВыгрузкаДвижениеПоДокументу(Документ)
 
 //ДвиженияДокумента = Документ.Метаданные().Движения;
 
 
 Для каждого НаборЗаписей Из Документ.ПолучитьОбъект().Движения Цикл
  НаборЗаписей.Прочитать();
       СериализаторXDTO.ЗаписатьXML(Запись, НаборЗаписей);
   
 
 КонецЦикла;
 
 
 //ТаблицаДвижений = ОпределитьНаличиеДвиженийПоРегистратору(Документ);
 //
 //Для Каждого СтрокаТаблицыДвижений Из ТаблицаДвижений Цикл
 // 
 // СтрокаТаблицыДвижений.Имя = Врег(СокрЛП(СтрокаТаблицыДвижений.Имя));
 // 
 //КонецЦикла;
 //
 //Для Каждого СвойстваОбъекта Из ДвиженияДокумента Цикл
 // СтрокаВТаблицеРегистров = ТаблицаДвижений.Найти(Врег(СвойстваОбъекта.ПолноеИмя()), "Имя");
 // Если СтрокаВТаблицеРегистров = Неопределено Тогда
 //  Продолжить;
 // КонецЕсли;
 // 
 // 

 // //СериализаторXDTO.ЗаписатьXML(Запись, СтрокаВТаблицеРегистров);
 //КонецЦикла;
КонецПроцедуры

Процедура ОсновныеДействияФормыКнопкаВыгрузить(Кнопка)
 ДиалогОткрытияФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);
 ДиалогОткрытияФайла.Заголовок = "Выберите файл xml";
 ДиалогОткрытияФайла.Фильтр = "Формат xml(*.xml)|*.xml";
 ДиалогОткрытияФайла.ПроверятьСуществованиеФайла = Истина;
 Если Не ДиалогОткрытияФайла.Выбрать() тогда
  возврат;
 КонецЕсли;
 
 
 
 
 Запись = Новый ЗаписьXML; 
 
 Запись.ОткрытьФайл(ДиалогОткрытияФайла.ПолноеИмяФайла);
 
 //записываем объявление xml файла:  
 Запись.ЗаписатьОбъявлениеXML(); 
 
 //записываем корневой элемент, по спецификации xml он может быть только один, назовем его "Данные" 
 Запись.ЗаписатьНачалоЭлемента("Данные"); 
 
 //для того чтобы пространства имен не объявлялись сериализатором в кажом элементе, пишем их в корневой элемент 
 //они будут работать на все вложеные элементы 
 //пространство имен по-умолчанию 
 Запись.ЗаписатьСоответствиеПространстваИмен("", "http://v8.1c.ru/8.1/data/enterprise/current-config"); 
 
 //пространства имен остальные префиксы 
 Запись.ЗаписатьСоответствиеПространстваИмен("xsd", "http://www.w3.org/2001/XMLSchema"); 
 Запись.ЗаписатьСоответствиеПространстваИмен("xsi", "http://www.w3.org/2001/XMLSchema-instance"); 
 Если ФлажокВыгрузкаСВязанных тогда
  ОбработкаМетаданных(ОбъектдляВыгрузки);
 КонецЕсли;
 
 
 Если  ФлажокВыгружатьПодчиненные тогда
  
  Запрос = Новый Запрос;
  Запрос.Текст = 
  "ВЫБРАТЬ
  | Ссылка
  |ИЗ
  | Справочник."+ОбъектдляВыгрузки.Метаданные().Имя+" КАК ЗапросПоСправочнику
  |ГДЕ
  | Родитель  В ИЕРАРХИИ(&Родитель)";
  
  Запрос.УстановитьПараметр("Родитель", ОбъектдляВыгрузки);
  Результат = Запрос.Выполнить();
  ВыборкаДетальныеЗаписи = Результат.Выбрать();  
  Пока ВыборкаДетальныеЗаписи.Следующий() Цикл   
   ОбработкаМетаданных(ВыборкаДетальныеЗаписи.Ссылка);
   СписокДляВыгрузки.Добавить()["Ссылка"]=(ВыборкаДетальныеЗаписи.Ссылка);
  КонецЦикла;
 КонецЕсли;
 
 Если ФлажокВыгружатьПоВладельцу тогда
  
  Для Каждого МетаданныеСправочника Из метаданные.Справочники Цикл
   Для Каждого Владелец Из МетаданныеСправочника.Владельцы Цикл 
    Если Владелец = ОбъектдляВыгрузки.Метаданные() тогда
     Запрос = Новый Запрос;
     Запрос.Текст = 
     "ВЫБРАТЬ
     | Ссылка
     |ИЗ
     | Справочник."+МетаданныеСправочника.Имя+" КАК ЗапросПоСправочнику
     |ГДЕ
     | Владелец В ИЕРАРХИИ(&Владелец)";
     
     Запрос.УстановитьПараметр("Владелец", ОбъектдляВыгрузки);
     Результат = Запрос.Выполнить();
     ВыборкаДетальныеЗаписи = Результат.Выбрать();  
     Пока ВыборкаДетальныеЗаписи.Следующий() Цикл   
      ОбработкаМетаданных(ВыборкаДетальныеЗаписи.Ссылка);
      СписокДляВыгрузки.Добавить()["Ссылка"]=(ВыборкаДетальныеЗаписи.Ссылка);
     КонецЦикла;
    КонецЕсли;
   КонецЦикла;
  КонецЦикла;
  
 КонецЕсли;
 
 Если ФлажокВыгружатьДвиженияДокумента тогда
  ВыгрузкаДвижениеПоДокументу(ОбъектдляВыгрузки);
 КонецЕсли;
 
 СписокДляВыгрузки.Свернуть("Ссылка");
 Для Каждого СтрокаТаблицы Из  СписокДляВыгрузки Цикл
  СериализаторXDTO.ЗаписатьXML(Запись, СтрокаТаблицы["Ссылка"].ПолучитьОбъект());  
 КонецЦикла;
 
 СериализаторXDTO.ЗаписатьXML(Запись, ОбъектдляВыгрузки.ПолучитьОбъект()); 
 
 
 //записываем конец корневого элемента 
 Запись.ЗаписатьКонецЭлемента(); 
 Запись.Закрыть();
 //Заменить(ФЛ);
 
КонецПроцедуры

Процедура ОсновныеДействияФормыКнопкаЗагрузить(Кнопка)
 ДиалогОткрытияФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
 ДиалогОткрытияФайла.Заголовок = "Выберите файл xml";
 ДиалогОткрытияФайла.Фильтр = "Формат xml(*.xml)|*.xml";
 ДиалогОткрытияФайла.ПроверятьСуществованиеФайла = Истина;
 Если Не ДиалогОткрытияФайла.Выбрать() тогда
  возврат;
 КонецЕсли;
 Чтение = Новый ЧтениеXML;
 Чтение.ОткрытьФайл(ДиалогОткрытияФайла.ПолноеИмяФайла);
 //прочитаем начало xml файла 
 Чтение.ПерейтиКСодержимому(); 
 
 //прочитаем начало корневого элемента 
 Чтение.Прочитать(); 
 
 //читаем содержимое пока текущим не станет конец корневого элемента, т.к. мы писали туда только целые элементы справочника, 
 //а сериализатор читает каждый из их полностью, то мы упремся именно в конец корневого 
 ЗагруженоОбъектов=0;
 НачатьТранзакцию();
 Пока Чтение.ТипУзла<>ТипУзлаXML.КонецЭлемента Цикл 
  ЗагруженоОбъектов = ЗагруженоОбъектов+1;
  Если ЗагруженоОбъектов%1000 тогда
   ЗафиксироватьТранзакцию();
   НачатьТранзакцию();
  КонецЕсли;
  //читаем очередной элемент справочника 
  Объект = СериализаторXDTO.ПрочитатьXML(Чтение); 
  Объект.ОбменДанными.Загрузка = Истина;
  Объект.Записать();
  //покажем что прочитали, осталось только записать объект 
  Сообщить(""+ТипЗнч(Объект)+" - "+Объект); 
 КонецЦикла; 
 ЗафиксироватьТранзакцию();
 Чтение.Закрыть();
КонецПроцедуры

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


СписокДляВыгрузки = новый ТаблицаЗначений;
СписокДляВыгрузки.Колонки.Добавить("Ссылка");

СписокОбщий = новый ТаблицаЗначений;
СписокОбщий.Колонки.Добавить("Ссылка");

Запись = Новый ЗаписьXML; 

Friday, July 8, 2011

реиндексация ms sql 2008

declare @minRows int

set @minRows = 100


declare @reindexQuery nvarchar(max)


set @reindexQuery =

REPLACE(REPLACE(

cast(

(

select

'BEGIN TRY ALTER INDEX '+idx.name+' ON '+ sc.name+'.'+ t.name+

CASE

WHEN st.avg_fragmentation_in_percent > 30 THEN ' REBUILD WITH (ONLINE=ON) END TRY BEGIN CATCH ALTER INDEX '+idx.name+' ON '+ sc.name+'.'+ t.name+ ' REBUILD WITH (ONLINE=OFF) END CATCH;'

ELSE ' REORGANIZE END TRY BEGIN CATCH END CATCH;'

END as query


from sys.dm_db_index_physical_stats( DB_ID(),NULL,NULL,NULL,NULL) st

join sys.tables t on (st.object_id=t.object_id)

join sys.schemas sc on (sc.schema_id=t.schema_id)

join sys.indexes idx on (t.object_id=idx.object_id and st.index_id=idx.index_id)

join sys.partitions p on (p.index_id=idx.index_id and p.object_id=idx.object_id)

where p.rows > @minRows and st.avg_fragmentation_in_percent > 5

order by st.avg_fragmentation_in_percent desc

FOR XML PATH(''), TYPE

) as nvarchar(max))

,'',';

'),'','')


print @reindexQuery


exec (@reindexQuery)

Tuesday, July 5, 2011

Описание с сайта Гилева по установке 1С 8

http://gilev.ru/1c/mssql/index.htm

Перестройка индексов MS SQL Server

USE db1cut
GO
DECLARE @MyTable varchar(252)
DECLARE @MyIndex varchar(252)
DECLARE @DSQL varchar(8000)
DECLARE MyCursor CURSOR FOR
SELECT o.name, i.name
FROM sysobjects o INNER JOIN sysindexes i ON o.id = i.id
WHERE (o.xtype = 'U') AND (INDEXPROPERTY(i.id, i.name, 'isStatistics') = 0) AND (i.dpages > 0)
ORDER BY o.name, i.indid

OPEN MyCursor
FETCH NEXT FROM MyCursor INTO @MyTable, @MyIndex
WHILE @@FETCH_STATUS=0

BEGIN
PRINT 'Перестройка индекса '+@MyIndex+' из таблицы '+@MyTable
SET @DSQL = ' BEGIN TRY
ALTER INDEX '+@MyIndex+' ON '+@MyTable+
' REBUILD WITH (ONLINE = ON,
SORT_IN_TEMPDB = ON,
STATISTICS_NORECOMPUTE = ON)
END TRY

BEGIN CATCH ALTER INDEX '+@MyIndex+' ON '+@MyTable+
' REBUILD WITH (ONLINE = OFF,
SORT_IN_TEMPDB = ON,
STATISTICS_NORECOMPUTE = ON) END CATCH;'
EXEC(@DSQL)

FETCH NEXT FROM MyCursor INTO @MyTable, @MyIndex

END
CLOSE MyCursor
DEALLOCATE MyCursor


как всегда спасибо Гилев

Friday, April 29, 2011

Объединение таблиц значений в 1С 8.х через запрос и временные таблицы

Запрос = Новый Запрос;
Запрос.Текст = "Выбрать * ПОМЕСТИТЬ ВремТабл Из &ТабЗнач1 как ТабЗнач1;
| Выбрать * ПОМЕСТИТЬ ВремТабл1 Из &ТабЗнач как ТабЗнач;
| Выбрать * ИЗ ВремТабл ОБЪЕДИНИТЬ ВСЕ Выбрать * ИЗ ВремТабл1";

Запрос.УстановитьПараметр("ТабЗнач",ТаблицаИсточник1);
Запрос.УстановитьПараметр("ТабЗнач1",ТаблицаИсточник2);
ИтоговаяТаблица = Запрос.Выполнить().Выгрузить();

Загрузка объектов xml через XDTO

ДиалогОткрытияФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
ДиалогОткрытияФайла.Заголовок = "Выберите файл xml";
ДиалогОткрытияФайла.Фильтр = "Формат xml(*.xml)|*.xml";
ДиалогОткрытияФайла.ПроверятьСуществованиеФайла = Истина;
Если Не ДиалогОткрытияФайла.Выбрать() тогда
возврат;
КонецЕсли;
Чтение = Новый ЧтениеXML;
Чтение.ОткрытьФайл(ДиалогОткрытияФайла.ПолноеИмяФайла);
//прочитаем начало xml файла
Чтение.ПерейтиКСодержимому();

//прочитаем начало корневого элемента
Чтение.Прочитать();

//читаем содержимое пока текущим не станет конец корневого элемента, т.к. мы писали туда только целые элементы справочника,
//а сериализатор читает каждый из их полностью, то мы упремся именно в конец корневого
Пока Чтение.ТипУзла<>ТипУзлаXML.КонецЭлемента Цикл

//читаем очередной элемент справочника
Объект = СериализаторXDTO.ПрочитатьXML(Чтение);
Объект.ОбменДанными.Загрузка = Истина;
Объект.Записать();
//покажем что прочитали, осталось только записать объект
Сообщить(""+ТипЗнч(Объект)+" - "+Объект);
КонецЦикла;

Чтение.Закрыть();

Friday, February 25, 2011

маркет плюс, средний чек

SELECT
SAREA.SAREANAME
--,Substring([SALESTIME],1,8) as [день]
--,Substring([SALESTIME],9,2) as [час]

--,[PACKNAME] as [фискалка]

,Sum(case [SALESREFUND] when 0 then [SALESSUM] else -1*[SALESSUM] end )/100 as [Сумма]
,Sum(case [SALESREFUND] when 0 then [SALESSUM] else -1*[SALESSUM] end )/100/Count([FRECNUM]) as [среднийчек]
,Count([FRECNUM]) as [чеков]



FROM [GuidForMP].[dbo].[SALES] [sales]
left join [GuidForMP].dbo.SAREA SAREA on SAREA.SAREAID=sales.SAREAID
where Substring([SALESTIME],1,6)='201101' and SALESTAG = 2 AND SALESCANC=0 AND sales.DELFLAG=0
group by SAREA.SAREANAME
--group by SAREA.SAREANAME,Substring([SALESTIME],1,8),Substring([SALESTIME],9,2),[PACKNAME]
--order by SAREA.SAREANAME,Substring([SALESTIME],1,8),Substring([SALESTIME],9,2),[PACKNAME]

Tuesday, February 22, 2011

Игры с построителем отчета в 1с

Необходимо было сделать отчет с анализатором остатков по дням, решил долго не мучатся и сделать через ПостроительОтчета в 1С. Необходимые поля:
1. Номенклатура+артикул
2. Дни (анализ делаем за каждый день)
3. Заказано (какое количество номенклатуры было заказано за период)
4. Отгружено (Считай приходные накладные)
5. Возврат (сколько вернули)
6. Остаток товара на конец дня
7. Маленький такой анализ % возврата.

Вид картинкой:


А теперь сам код:

Процедура ПередОткрытием(Отказ, СтандартнаяОбработка)
НачалоПериода = началоМесяца(ТекущаяДата());
КонецПериода = КонецДня(ТекущаяДата());
ОтчетИнициализация();

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

Процедура ПриЗакрытии()

//СохранитьЗначение("НастройкаВнешниеОбработкиВнешняяОбработка3Отчет_bc39e421-f272-414c-9c50-d1bfb9a20f26", ПостроительОтчетаОтчет.ПолучитьНастройки());

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

Процедура ДействияФормыОтчетНастройка(Кнопка)
//{{КОНСТРУКТОР_ВЫХОДНЫХ_ФОРМ_ПОСТРОИТЕЛЬОТЧЕТА_НАСТРОЙКА(Отчет)
// Данный фрагмент построен конструктором.
// При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!

Форма = ВнешняяОбработкаОбъект.ПолучитьФорму("ОтчетНастройка");
//ПостроительОтчетаОтчет.ИзмеренияКолонки.Добавить("Дата");
//ПостроительОтчетаОтчет.ИзмеренияКолонки.Удалить(ПостроительОтчетаОтчет.ИзмеренияКолонки[0]);
Форма.ПостроительОтчета = ПостроительОтчетаОтчет;
Настройка = ПостроительОтчетаОтчет.ПолучитьНастройки();
Если Форма.ОткрытьМодально() = Истина Тогда
ОтчетВывести();
Иначе
ПостроительОтчетаОтчет.УстановитьНастройки(Настройка);
КонецЕсли;

//}}КОНСТРУКТОР_ВЫХОДНЫХ_ФОРМ_ПОСТРОИТЕЛЬОТЧЕТА_НАСТРОЙКА
КонецПроцедуры

Процедура ДействияФормыОтчетСформировать(Кнопка)
//{{КОНСТРУКТОР_ВЫХОДНЫХ_ФОРМ_ПРОЦЕДУРА_ВЫЗОВА(Отчет)
// Данный фрагмент построен конструктором.
// При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!

ОтчетВывести();

//}}КОНСТРУКТОР_ВЫХОДНЫХ_ФОРМ_ПРОЦЕДУРА_ВЫЗОВА
КонецПроцедуры

Процедура ОтчетВывести()
//{{КОНСТРУКТОР_ВЫХОДНЫХ_ФОРМ_ПОСТРОИТЕЛЬОТЧЕТА_ВЫПОЛНИТЬ(Отчет)
// Данный фрагмент построен конструктором.
// При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!
//ОтчетИнициализация();
ЭлементыФормы.ПолеТабличногоДокумента.Очистить();

ПостроительОтчетаОтчет.Параметры.Вставить("КонецПериода", КонецПериода);
ПостроительОтчетаОтчет.Параметры.Вставить("Контрагент", Контрагент);
ПостроительОтчетаОтчет.Параметры.Вставить("НачалоПериода", НачалоПериода);
ПостроительОтчетаОтчет.Параметры.Вставить("ПодразделениеКомпании", ПодразделениеКомпании);
ПостроительОтчетаОтчет.ТекстЗаголовка = "Анализ заказов по " + ПодразделениеКомпании.Наименование +Символы.ПС
+ " контрагент " + Контрагент.Наименование
+" период с  " + Формат(НачалоПериода,"ДФ=dd.MM.yyyy")+ " по " + Формат(КонецПериода,"ДФ=dd.MM.yyyy");

ПостроительОтчетаОтчет.Выполнить();
ПостроительОтчетаОтчет.РазмещениеИзмеренийВСтроках = ТипРазмещенияИзмерений.Вместе;
ПостроительОтчетаОтчет.РазмещениеРеквизитовИзмеренийВСтроках = ТипРазмещенияРеквизитовИзмерений.Отдельно;
ПостроительОтчетаОтчет.РазмещениеРеквизитовИзмеренийВКолонках = ТипРазмещенияРеквизитовИзмерений.Отдельно;

ПостроительОтчетаОтчет.МакетОформления = ПолучитьМакетОформления(СтандартноеОформление.Песок);



Макет=ПостроительОтчетаОтчет.Макет;
Область = Макет.Область();
Область.ШиринаКолонки = 10;
Линия = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная,1);
ТекущаяОбласть = Неопределено;

ТекущаяОбласть = Макет.НайтиТекст("Номенклатура", ТекущаяОбласть, Макет.Область());
Если ТекущаяОбласть <> Неопределено Тогда
ТекущаяОбласть.ШиринаКолонки  = 70;
ТекущаяОбласть.Обвести(Линия,Линия,Линия,Линия);
КонецЕсли;

ТекущаяОбласть = Макет.НайтиТекст("Артикул", ТекущаяОбласть, Макет.Область());
Если ТекущаяОбласть <> Неопределено Тогда
ТекущаяОбласть.ШиринаКолонки  = 8;
ТекущаяОбласть.Обвести(Линия,Линия,Линия,Линия);
КонецЕсли;

ТекущаяОбласть = Макет.НайтиТекст("Заказано", ТекущаяОбласть, Макет.Область());
Если ТекущаяОбласть <> Неопределено Тогда
ТекущаяОбласть.ШиринаКолонки  = 8;
ТекущаяОбласть .Обвести(Линия,Линия,Линия,Линия);
КонецЕсли;

ТекущаяОбласть = Макет.НайтиТекст("Отгружено", ТекущаяОбласть, Макет.Область());
Если ТекущаяОбласть <> Неопределено Тогда
ТекущаяОбласть.ШиринаКолонки  = 8;
ТекущаяОбласть .Обвести(Линия,Линия,Линия,Линия);
КонецЕсли;

ТекущаяОбласть = Макет.НайтиТекст("Возврат", ТекущаяОбласть, Макет.Область());
Если ТекущаяОбласть <> Неопределено Тогда
ТекущаяОбласть.ШиринаКолонки  = 8;
ТекущаяОбласть .Обвести(Линия,Линия,Линия,Линия);
КонецЕсли;

ТекущаяОбласть = Макет.НайтиТекст("Остаток", ТекущаяОбласть, Макет.Область());
Если ТекущаяОбласть <> Неопределено Тогда
ТекущаяОбласть.ШиринаКолонки  = 8;
ТекущаяОбласть .Обвести(Линия,Линия,Линия,Линия);
КонецЕсли;

ТекущаяОбласть = Макет.НайтиТекст("ПроцентВозврата", ТекущаяОбласть, Макет.Область());
Если ТекущаяОбласть <> Неопределено Тогда
ТекущаяОбласть.ШиринаКолонки  = 0;
ТекущаяОбласть.Видимость=Ложь;

КонецЕсли;

ПостроительОтчетаОтчет.Макет = Макет;



ПостроительОтчетаОтчет.Вывести(ЭлементыФормы.ПолеТабличногоДокумента);
ЭлементыФормы.ПолеТабличногоДокумента.ФиксацияСверху=5;
ЭлементыФормы.ПолеТабличногоДокумента.ФиксацияСлева=3;
//}}КОНСТРУКТОР_ВЫХОДНЫХ_ФОРМ_ПОСТРОИТЕЛЬОТЧЕТА_ВЫПОЛНИТЬ
КонецПроцедуры

Процедура ОтчетИнициализация()
//{{КОНСТРУКТОР_ВЫХОДНЫХ_ФОРМ_ПОСТРОИТЕЛЬОТЧЕТА_ИНИЦИАЛИЗАЦИЯ(Отчет)
// Данный фрагмент построен конструктором.
// При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!
Текст = "";
СчДней=Формат(НачалоПериода,"ДФ=yyyyMMdd");
ДатаЦикла=КонецДня(НачалоПериода);

Текст =
"ВЫБРАТЬ
|   &Д"+СчДней+" КАК Период,
|   ПартииТоваровКомпанииОстатки.Номенклатура,
|   ПартииТоваровКомпанииОстатки.Номенклатура.Артикул Как Артикул,
|   ПартииТоваровКомпанииОстатки.КоличествоОстаток КАК Остаток
|   ПОМЕСТИТЬ ТемпОст
|ИЗ
|   РегистрНакопления.ПартииТоваровКомпании.Остатки(&Д"+СчДней+",СкладКомпании.Подразделение=&ПодразделениеКомпании И Партия.Контрагент=&Контрагент) КАК ПартииТоваровКомпанииОстатки
|   ";

ПостроительОтчетаОтчет.Параметры.Вставить("Д"+СчДней, началоПериода);
Пока ДатаЦикла <= КонецПериода  Цикл

ДатаЦикла=КонецДня(ДатаЦикла+2);
СчДней = Формат(ДатаЦикла,"ДФ=yyyyMMdd");

Текст = Текст +
"
|ОБЪЕДИНИТЬ ВСЕ
|ВЫБРАТЬ
|   &Д"+СчДней+" КАК Период,
|   ПартииТоваровКомпанииОстатки.Номенклатура,
|   ПартииТоваровКомпанииОстатки.Номенклатура.Артикул,
|   ПартииТоваровКомпанииОстатки.КоличествоОстаток
|ИЗ
|   РегистрНакопления.ПартииТоваровКомпании.Остатки(&Д"+СчДней+",СкладКомпании.Подразделение=&ПодразделениеКомпании И Партия.Контрагент= &Контрагент) КАК ПартииТоваровКомпанииОстатки
|";
ПостроительОтчетаОтчет.Параметры.Вставить("Д"+СчДней, ДатаЦикла);
КонецЦикла;
СчДней= Формат(КонецПериода,"ДФ=yyyyMMdd");
Текст = Текст+
"
|;
|ВЫБРАТЬ
|   ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(ЗаказПоставщикуТовары.Ссылка.Дата, ДЕНЬ), ДЕНЬ, 1) КАК Дата,
|   ЗаказПоставщикуТовары.Номенклатура КАК Номенклатура,
|   ЗаказПоставщикуТовары.Номенклатура.Артикул КАК Артикул,
|   СУММА(ЗаказПоставщикуТовары.Количество) КАК Заказано,
|   СУММА(0) КАК Отгружено,
|   СУММА(0) КАК Возврат,
|   СУММА(0) КАК Остаток,
|   СУММА(0) КАК ПроцентВозврата
|ИЗ
|   Документ.ЗаказПоставщику.Товары КАК ЗаказПоставщикуТовары
|ГДЕ
|   ЗаказПоставщикуТовары.Ссылка.Дата МЕЖДУ НАЧАЛОПЕРИОДА(&НачалоПериода, ДЕНЬ) И КОНЕЦПЕРИОДА(&КонецПериода, ДЕНЬ)
|   И ЗаказПоставщикуТовары.Ссылка.Контрагент = &Контрагент
|   И ЗаказПоставщикуТовары.Ссылка.Проведен
|   И ЗаказПоставщикуТовары.Ссылка.ПодразделениеКомпании = &ПодразделениеКомпании
|
|СГРУППИРОВАТЬ ПО
|   ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(ЗаказПоставщикуТовары.Ссылка.Дата, ДЕНЬ), ДЕНЬ, 1),
|   ЗаказПоставщикуТовары.Номенклатура,ЗаказПоставщикуТовары.Номенклатура.Артикул
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
|   НАЧАЛОПЕРИОДА(ПоступлениеТоваровТовары.Ссылка.Дата, ДЕНЬ),
|   ПоступлениеТоваровТовары.Номенклатура,
|   ПоступлениеТоваровТовары.Номенклатура.Артикул,
|   СУММА(0),
|   СУММА(ПоступлениеТоваровТовары.Количество),
|   СУММА(0),
|   СУММА(0),
|   СУММА(0)
|ИЗ
|   Документ.ПоступлениеТоваров.Товары КАК ПоступлениеТоваровТовары
|ГДЕ
|   ПоступлениеТоваровТовары.Ссылка.Дата МЕЖДУ НАЧАЛОПЕРИОДА(&НачалоПериода, ДЕНЬ) И КОНЕЦПЕРИОДА(&КонецПериода, ДЕНЬ)
|   И ПоступлениеТоваровТовары.Ссылка.Контрагент = &Контрагент
|   И ПоступлениеТоваровТовары.Ссылка.Проведен
|   И ПоступлениеТоваровТовары.Ссылка.ПодразделениеКомпании = &ПодразделениеКомпании
|
|СГРУППИРОВАТЬ ПО
|   НАЧАЛОПЕРИОДА(ПоступлениеТоваровТовары.Ссылка.Дата, ДЕНЬ),
|   ПоступлениеТоваровТовары.Номенклатура,ПоступлениеТоваровТовары.Номенклатура.Артикул
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
|   НАЧАЛОПЕРИОДА(ВозвратПоставщикуТовары.Ссылка.Дата, ДЕНЬ),
|   ВозвратПоставщикуТовары.Номенклатура,
|   ВозвратПоставщикуТовары.Номенклатура.Артикул,
|   СУММА(0),
|   СУММА(0),
|   СУММА(ВозвратПоставщикуТовары.Количество),
|   СУММА(0),
|   СУММА(0)
|ИЗ
|   Документ.ВозвратПоставщику.Товары КАК ВозвратПоставщикуТовары
|ГДЕ
|   ВозвратПоставщикуТовары.Ссылка.Дата МЕЖДУ НАЧАЛОПЕРИОДА(&НачалоПериода, ДЕНЬ) И КОНЕЦПЕРИОДА(&КонецПериода, ДЕНЬ)
|   И ВозвратПоставщикуТовары.Ссылка.Контрагент = &Контрагент
|   И ВозвратПоставщикуТовары.Ссылка.Проведен
|   И ВозвратПоставщикуТовары.Ссылка.ПодразделениеКомпании = &ПодразделениеКомпании
|
|СГРУППИРОВАТЬ ПО
|   НАЧАЛОПЕРИОДА(ВозвратПоставщикуТовары.Ссылка.Дата, ДЕНЬ),
|   ВозвратПоставщикуТовары.Номенклатура,ВозвратПоставщикуТовары.Номенклатура.Артикул
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
|   НАЧАЛОПЕРИОДА(ТемпОст.Период, ДЕНЬ),
|   ТемпОст.Номенклатура,
|   ТемпОст.Артикул,
|   СУММА(0),
|   СУММА(0),
|   СУММА(0),
|   СуММА(ТемпОст.Остаток),
|   СУММА(0)
|ИЗ
|   ТемпОст КАК ТемпОст
|СГРУППИРОВАТЬ ПО
|   НАЧАЛОПЕРИОДА(ТемпОст.Период, ДЕНЬ),
|   ТемпОст.Номенклатура, ТемпОст.Артикул
|
|УПОРЯДОЧИТЬ ПО
|   Дата,
|   Номенклатура
|ИТОГИ
|   СУММА(Заказано),
|   СУММА(Отгружено),
|   СУММА(Возврат),
|   ВЫразить(Среднее(Остаток) КАК ЧИсло(12,2)) КАК Остаток,
|   ВЫбор КОгда СУММА(Отгружено)=0 тогда 0 ИНАЧЕ Выразить(СУММА(Возврат)/СУММА(Отгружено)*100 КАК Число(12,2)) КОНЕЦ КАК ПроцентВозврата
|ПО
|   ОБЩИЕ,
|   Дата,
|   Номенклатура ИЕРАРХИЯ";
ПостроительОтчетаОтчет.Текст = Текст;
ПостроительОтчетаОтчет.ЗаполнитьНастройки();
ПостроительОтчетаОтчет.ЗаполнениеРасшифровки = ВидЗаполненияРасшифровкиПостроителяОтчета.ЗначенияГруппировок;
ПостроительОтчетаОтчет.ТекстЗаголовка = "Анализ заказов по " + ПодразделениеКомпании.НаименованиеПолное +Символы.ПС +" период с  " + Формат(НачалоПериода,"ДФ=dd.MM.yyyy")+ " по " + Формат(КонецПериода,"ДФ=dd.MM.yyyy");
//Настройка = ВосстановитьЗначение("НастройкаВнешниеОбработкиВнешняяОбработка3Отчет_bc39e421-f272-414c-9c50-d1bfb9a20f26");
//  Если Настройка <> Неопределено Тогда
//      ПостроительОтчетаОтчет.УстановитьНастройки(Настройка);
//  КонецЕсли;

ПостроительОтчетаОтчет.ИзмеренияСтроки.Очистить();
ПостроительОтчетаОтчет.ИзмеренияКолонки.Очистить();
ПостроительОтчетаОтчет.ИзмеренияСтроки.Добавить("Номенклатура","Номенклатура",ТипИзмеренияПостроителяОтчета.Иерархия);
ПостроительОтчетаОтчет.ИзмеренияКолонки.Добавить("Дата");
//ПостроительОтчетаОтчет.ИзмеренияСтроки.Удалить(ПостроительОтчетаОтчет.ИзмеренияСтроки[0]);
//ПостроительОтчетаОтчет.ИзмеренияКолонки.Добавить("Дата");
//ПостроительОтчетаОтчет.ИзмеренияКолонки.Удалить(ПостроительОтчетаОтчет.ИзмеренияКолонки[0]);
//}}КОНСТРУКТОР_ВЫХОДНЫХ_ФОРМ_ПОСТРОИТЕЛЬОТЧЕТА_ИНИЦИАЛИЗАЦИЯ
КонецПроцедуры

Процедура ВыбПериодНажатие(Элемент)
НастройкаПериода = Новый НастройкаПериода;
НастройкаПериода.УстановитьПериод(НачалоПериода, ?(КонецПериода='0001-01-01', КонецПериода, КонецДня(КонецПериода)));
НастройкаПериода.РедактироватьКакИнтервал = Истина;
НастройкаПериода.РедактироватьКакПериод = Истина;
НастройкаПериода.ВариантНастройки = ВариантНастройкиПериода.Период;
Если НастройкаПериода.Редактировать() Тогда
НачалоПериода = НастройкаПериода.ПолучитьДатуНачала();
КонецПериода = НастройкаПериода.ПолучитьДатуОкончания();
КонецЕсли;
ОтчетИнициализация();
КонецПроцедуры

Процедура НачалоПериодаПриИзменении(Элемент)
ОтчетИнициализация();
КонецПроцедуры

Процедура КонецПериодаПриИзменении(Элемент)
ОтчетИнициализация();
КонецПроцедуры




Основная задача отчета построить шахматкой данные за период в днях.
Основные сложности, это
1. Получить остатки за каждый день
2. Заставить построитель всегда работать правильно со строками и колонками
3. Нормализация ширины колонок.

Friday, February 18, 2011

Работа с выбором дат в 1С запросе, если даты могут быть пустыми

&ТекущаяДата МЕЖДУ ВЫБОР
КОГДА ДоговорыВзаиморасчетов.ДатаНачала = ДАТАВРЕМЯ(1, 1, 1, 0, 0, 0)
ТОГДА НАЧАЛОПЕРИОДА(&ТекущаяДата, ГОД)
ИНАЧЕ ДоговорыВзаиморасчетов.ДатаНачала
КОНЕЦ И ВЫБОР
КОГДА ДоговорыВзаиморасчетов.ДатаКонца = ДАТАВРЕМЯ(1, 1, 1, 0, 0, 0)
ТОГДА КОНЕЦПЕРИОДА(ДоговорыВзаиморасчетов.ДатаКонца, ГОД)
ИНАЧЕ ДоговорыВзаиморасчетов.ДатаКонца
КОНЕЦ

Wednesday, July 7, 2010

motorola ap-5131

Установка motorola ap-5131
1. Для того что бы сбросить пароль необходимо подключиться через com port. Использовал putty.
1.1. В программе putty устанавливал следующие значения:





















не забываем про кодировку


1.2. После подключения вынимаем с AP кабель сети(он же питания) и вставляем его обратно. И сразу же смотрим в putty:


1.3. Жмем в течении 3 минут ESC

1.4. Сбрасываем пароль: passwd default

1.5. Перегружаем систему: reset system

1.6. После перезагрузки вводим пользователя admin пароль symbol или motorola

1.7. После установки нового пароля смотрим, что же твориться в системе командой summary
1.8. Вот теперь изучив настройки пробуем подключится к точке через броузер

1.9. Подключаем кабель ккомпьютору и к точке WAN

1.10. Устанавливаем настройку сетевой карты на компе
1.11. Не забыть установить Java

1.12. Стучимся с броузера по https://10.1.1.1

1.13. И дальше уже по документации









Wednesday, March 24, 2010

По ИНН расчет день рождений и пола

- 1-5 числа количество дней с 1 января 1900 года по день рождения человека.
- 6-9 порядковый номер среди всех граждан страны, родившихся в этот день, присваивается исходя из региона налоговой, выдавшей ИНН, причем 9 цифра четная - жен. нечетная - муж.
- 10 - контрольная, как в штрих-коде, как вычисляется - не знаю.

Sunday, October 11, 2009

Задумался на транслитерацией

Транслитерация — Википедия
ГОСТ российский
по госту перегоняем:
а|б|в|г|д|е|ё|ж|з|и|й|к|л|м|н|о|п|р|с|т|у|ф|х|ц|ч|ш|щ|ъ|ы|ь|э|ю|я
a|b|v|g|d|e|yo|zh|z|i|j|k|l|m|n|o|p|r|s|t|u|f|h|cz|ch|sh|shh|''|y'|'|e'|yu|ya