V tomto článku vám povím o funkci rychlého vyhledávání 1C Enterprise 8. Co je rychlé vyhledávání? Velmi jednoduché. Rychlé vyhledávání je jedním ze způsobů, jak procházet velké seznamy záznamů 1C. Mohou to být seznamy dokumentů, adresářů, registrů - vše, co je reprezentováno tabulkami.

Co je rychlé vyhledávání?

Funkce rychlého vyhledávání v dokumentech 1C Enterprise je velmi pohodlná a umožňuje vám neprocházet obrovským množstvím dat (například pomocí posuvníku), ale přejít přímo na požadované místo v seznamu. Naneštěstí začínající uživatelé 1C Enterprise 8 (včetně 1C Accounting 8) nejprve nepoužívají možnosti rychlého vyhledávání, raději procházejí seznamy dokumentů ručně (a mohou být vysoce velký). Tento článek vám pomůže pochopit, jak používat rychlé vyhledávání v 1C.

Nejprve je třeba poznamenat, že v konfiguracích 1C Enterprise 8, postavených na spravovaných formulářích, rychlé vyhledávání funguje jinak než v předchozích verzích 1C. Proto budeme zvlášť analyzovat použití rychlého vyhledávání ve spravovaných formulářích a v běžných formách.

Rychlé vyhledávání v účetnictví 1C 8.2

Ve verzích účetnictví 1C od 8,0 do 8,2 funkce je určena speciálně pro přechod do požadované části seznamu. Podívejte se například na okno účtové osnovy zobrazené na obrázku.


V okně je zvýrazněna určitá čára. Všimněte si jemného trojúhelníku pruhů označeného červenou šipkou. Stejně jako v jiných programech Windows, kde jsou seznamy (např. V Průzkumníkovi), určuje umístění této značky (trojúhelníku) řazení seznamu jako celku - ve kterém sloupci je značka nastavena, bude celý seznam seřazen podle tohoto sloupce. Na obrázku je značka ve sloupci Kód, proto budou účty v účtové osnově seřazeny podle kódu.

Značku lze přesouvat z jednoho sloupce do druhého kliknutím na požadovaný sloupec ( na záhlaví sloupce!) pomocí myši. Pokud je značka již v aktuálním sloupci, kliknutím změníte směr řazení na opačný (tj. Z většího na menší nebo naopak). Toto je standardní chování pro jakýkoli program Windows. Jaká je zvláštnost této značky v 1C Enterprise a jak souvisí s rychlým vyhledáváním?

Rychlé vyhledávání v seznamech 1C Enterprise 8 se provádí podle sloupce, ve kterém je značka umístěna. V takovém případě bude rychlé vyhledávání v účtové osnově provedeno ve sloupci Kód.

Toto byla důležitá součást článku, ale bez JavaScriptu to není vidět!

Jak používat rychlé vyhledávání v 1C? Snadný! Do tohoto sloupce začněte psát, co chcete najít, tj. kde je značka. V příkladu na obrázku výše je třeba zadat číslo účtu. Například chcete najít účet 50 Pokladník. V tomto případě zadejte ( nemusíte nikde klikat!) číslo 50 z klávesnice, a pokud je v tomto sloupci účet s tímto číslem (a samozřejmě existuje), seznam se posune na tento řádek a samotný řádek bude zvýrazněn. Výsledek je uveden na snímku obrazovky účtové osnovy níže.

webová stránka_

Text, na který ukazuje šipka, je není třeba umýt - on sám zmizí.

Pokud v uvedeném příkladu začnete zadávat slovo „Pokladník“, bude text ve spodní části okna zadán a poté vymazán. To se stane, protože jakmile start zadaného řetězce rychlého vyhledávání se již neshoduje se začátkem alespoň jednoho řádku v tomto sloupci, 1C Enterprise dojde k závěru, že hledaný řetězec nebyl nalezen, a automaticky jej vymaže. Pokud jde o je třeba si pamatovat dvě pravidla.

V 1C Enterprise 8 se rychlé vyhledávání provádí na začátku řádku, tj. sloupec hledá shodu zadaného textu se začátkem jednoho z řádků tohoto sloupce.
Z toho vyplývá důležité doporučení: při zadávání dat do adresářů pojmenujte prvky tak, aby bylo vhodné je rychle vyhledat. Například název dodavatele je lépe napsán jako „NameFirm LLC“ než „LLC NameFirmy“. Kromě toho byste v nadpisu neměli používat uvozovky a další zbytečné symboly (mluvíme o vyplňování pole Jméno ve formulářích).

Pokud začnete psát text, ale bude vymazán, to, co hledáte, není v tomto sloupci! V takovém případě zkontrolujte vstupní jazyk a také sloupec, ve kterém se provádí rychlé vyhledávání. Typickou chybou je nesprávný sloupec. Značka je například nastavena ve sloupci Kód a vyhledávání se provádí podle názvu účtu.

Rychlé vyhledávání v účetnictví 1C 8.3

Nyní se podívejme, jak se rychlé vyhledávání liší v 1C Enterprise 8.3. Využití je velmi podobné 8.2, ale je třeba pamatovat na jeden podstatný rozdíl.

V 1C Accounting 8.3, stejně jako v jiných konfiguracích na spravovaných formulářích (stejné nové rozhraní), funguje jako filtr. Jednoduše řečeno, v důsledku funkce rychlého vyhledávání je část seznamu úkryt.

Jak to použít, zjistíme nyní. Nejprve se podívejte na snímek obrazovky účtové osnovy 1C Accounting 8.3 níže.

webová stránka_

Jak vidíte, stejná značka je v jednom ze sloupců. Hledání také provádí sloupec, ve kterém je značka nastavena. To vše zůstalo nezměněno. Pokud však začnete zadávat text (v příkladu číslo účtu), stane se následující.

webová stránka_

Jak vidíte, vyhledávací pole se otevřelo automaticky. Stejné okno se otevře, když kliknete na tlačítko vyhledávání na panelu nástrojů okna (podtrženo na obrázku). Výsledkem je, že když kliknete na tlačítko Najít ve vyhledávacím okně (skryto za rozbalovací nabídkou na obrázku) nebo jednoduše vstoupíte, získáte následující výsledek.

webová stránka_

Z toho je jasné, že rychlé vyhledávání v 1C Accounting 8.3 ponechává viditelnou část seznamu, která splňuje podmínky vyhledávání. V takovém případě tlačítko Najít zmizí a místo toho se objeví čočka s křížkem (podtrženo na obrázku), po kliknutí na něj se seznam vrátí do původního stavu (zatímco čára nalezená v důsledku rychlého hledání zůstane zvýrazněno).

Další důležitá vlastnost rychlého vyhledávání v 1C Accounting 8.3 - shoda se nehledá na začátku řádku, jako ve verzi 8.2, ale vyhledá se shoda s jakoukoli částí řádků ve sloupci. Pokud se tedy protistraně říká „NameFirm LLC“, a při vyhledávání začněte zadávat „NameFirm LLC“, bude linka stále nalezena!

Vyvozování závěrů

Rychlé vyhledávání v 1C Accounting 8.2 a starších je tedy určeno k posouvání seznamu na požadovaný řádek a v 1C Accounting 8.3 funguje rychlé vyhledávání jako běžný filtr, který skryje část seznamu, kterou nepotřebujete.

Existuje několik mechanismů pro práci s řetězci v dotazech 1C. Nejprve lze přidat řádky. Za druhé, můžete si vzít podřetězec z řetězce. Za třetí, řetězce lze porovnávat, včetně vzorů. To je pravděpodobně vše, co můžete s řetězci dělat.

Zřetězení řetězců

K přidání řetězců do dotazu se používá operace „+“. Lze přidat pouze řádky omezené délky.

VYBERTE "Název:" + Protistrany. Název AS Sloupec 1 Z Adresáře. Dodavatelé AS Protistrany WHERE Protistrany. Odkaz \u003d & Odkaz

Funkce podřetězce

PODKLAD (<Строка>, <НачальнаяПозиция>, <Длина>)

Analogická funkce prostředí () z objektového modelu. Funkci Substring () lze použít na data typu řetězce a umožňuje vybrat fragment <Строки> počínaje číslem znaku <НачальнаяПозиция> (znaky v řetězci jsou očíslovány od 1) a délka <Длина> postavy. Výsledek vyhodnocení funkce má typ řetězce s proměnnou délkou a délka bude považována za neomezenou, pokud <Строка> má neomezenou délku a parametr <Длина> není konstantní nebo přesahuje 1024.

Pokud je délka řetězce menší než zadaná ve druhém parametru, vrátí funkce prázdný řetězec.

Pozornost! Použití funkce SUBSTRING () k převodu řetězců neomezené délky na řetězce omezené délky se nedoporučuje. Místo toho je lepší použít operaci obsazení EXPRESS ().

Funkce jako

Pokud se potřebujeme ujistit, že atribut řetězce splňuje určitá kritéria, porovnáme jej:

VYBRAT protistrany. Název AS Sloupec 1 Z adresáře. Protistrany AS Protistrany WHERE Protistrany. Název \u003d "Gazprom"

Ale co když chcete složitější srovnání? Nejen rovnost nebo nerovnost, ale jako určitý vzor? To je přesně to, pro co je vytvořena funkce LIKE.

LIKE - Operátor pro kontrolu řetězce jako vzoru. Analog LIKE v SQL.

Operátor LIKE umožňuje porovnat hodnotu zadaného výrazu nalevo od něj s řetězcem šablony určeným vpravo. Hodnota výrazu musí být typu string. Pokud hodnota výrazu odpovídá vzoru, vrátí operátor hodnotu TRUE, jinak bude FALSE.

Následující znaky v řetězci šablony jsou servisní znaky a mají jiný význam než znak řetězce:

  • % (procenta): sekvence obsahující libovolný počet libovolných znaků;
  • _ (podtržítko): jeden libovolný znak;
  • […] (Jeden nebo více znaků v hranatých závorkách): jakýkoli jeden znak uvedený v hranatých závorkách. Výčet může obsahovat rozsahy, například a-z, což znamená libovolný znak zahrnutý v rozsahu, včetně konců rozsahu;
  • [^…] (V hranatých závorkách znak negace následovaný jedním nebo více znaky): libovolný jeden znak, kromě těch, které jsou uvedeny za znakem negace.

Jakýkoli jiný symbol znamená sám sebe a nenese žádný další význam. Pokud jeden z uvedených znaků musí být zaznamenán jako sám, musí před ním být<Спецсимвол>... Sám<Спецсимвол> (jakýkoli vhodný znak) je definován ve stejném příkazu za klíčovým slovem SPECIÁLNÍ CHARAKTER.

Jmenuji se Pavel Barketov, pracuji pro Softpoint. Problémy s optimalizací výkonu řešíme již více než 10 let. A navzdory velkému počtu řešených problémů jejich počet neklesá, ale exponenciálně roste. Objemy dat se zvyšují a úkoly optimalizace práce s těmito daty se stávají obtížnějšími. Tento proces je nevyhnutelný.

Téma článku - netriviální přístupy k optimalizaci... Bude zváženo dva aspekty:

  • První - vyhledávání podřetězců... Uživatelé jej často používají a mnoho z nich již pravděpodobně čelilo významnému očekávání, že vyhledávání dílčích řetězců není dostatečně rychlé.
  • Druhý - držení velkých dokumentů, jako je uzavření měsíce, výpočet nákladů. Mnozí se jistě setkali se skutečností, že účetní tráví tyto dokumenty po dobu 5–9 hodin, v noci a mimo pracovní dobu. Nejzajímavější je, že klasické metody optimalizace zde ne vždy pomáhají. Pokud provádíte měření výkonu v debuggeru při provádění takových dokumentů, uvidíte, že největší čas strávíte zápisem do dočasných nebo skutečných struktur - tabulek, registrů atd. A je nemožné tento problém vyřešit klasickými metodami.

Hledání podle podřetězce

Prvním tématem je vyhledávání dílčích řetězců. Během tohoto roku jsem narazil na několik problémů s touto operací. Přicházíte do pojišťovny, abyste pojistku obnovili, nabízejí, že vás najdou podle telefonního čísla. Je jasné, že se nejedná o klasické hledání celého telefonního čísla, protože uživatel by mohl zadat číslo přes osm, přes sedm nebo něco jiného, \u200b\u200bproto hledá fragmenty čísla. V tomto případě se používají operace dlouhodobého vyhledávání - v řadě situací může být zpoždění několik sekund a může dokonce dosáhnout minut.

Hledání podle počátečních znaků

Začnu prvním příkladem, když se vyhledávání provádí na počátečních postavách. Jedná se o speciální případ hledání podřetězce, když uživatel ví jistě, že hledaná hodnota začíná určitými znaky.

Hledání podle počátečních znaků je implementováno v 1C pomocí příkazu LIKE (nebo v angličtině LIKE) s hodnotou s „%“ na konci („%“ označuje posloupnost dalších znaků). Například hledáme:

Název LIKE „ivano%“

Vezměte prosím na vědomí, že pokud máte index v tomto poli ve vašem systému, pak dotaz SQL použije pro toto hledání funkci Index Seek je indexové vyhledávání.

Podmínka „LIKE hledaný řetězec“ je ekvivalentní hledání v rozsahu hodnot... Ve zvláštním případě, když hledáme „ivano%“ - je to ekvivalentní hledání v řadě příjmení, která začínají na „ivano“ a končí na „ivanp“ (protože znak „p“ následuje za znakem „o“ ).

Moderní optimalizátory nezávisle převádějí LIKE dotaz na vyhledávací dotaz rozsahu... Pokud tedy máte ve svém systému index v tomto poli, získáte přesně stejný výsledek při interpretaci dotazu v podmínkách SQL - optimalizátor zobrazí dotaz s LIKE jako vyhledávání rozsahu.

Je tedy možné provést klasické rychlé vyhledávání pomocí indexového hledání. S tím nejsou žádné problémy, nebo je můžete vyřešit jednoduchým způsobem.

Hledat podle záznamu

Nyní si vezmeme složitější příklad, když není přesně známo, kde je v řetězci požadovaná hodnota, a hledání se provede výskytem řetězce. V tomto případě stojí v dotazu „LIKE“ „%“ na obou stranách.

Při převodu takového dotazu na SQL vidíme, že se mění pouze příkaz (hodnota již používá dvě „%“).

Pojďme se blíže podívat na plán provádění. Tady vidíme stejné hledání indexu, ale v tomto případě to nefunguje efektivně.

Faktem je, že index podle názvu referenční knihy, o kterém uvažujeme, se skládá z několika polí.

  • První je oddělovač účetnictví.
  • Další přímo je vyhledávací pole.

A proto, když se v plánu provádění zobrazí „Index Seek“, znamená to vyhledávání se provádí v prvním poli oddělovače - na snímku výše to vidíte vyhledávání na naší požadované hodnotě Desc se absolutně nepoužívá.

Co dělat v této situaci? V mé praxi bylo velmi často zakázáno uživatelům používat žádosti o vstup. A v některých případech samotní uživatelé tuto funkci nepoužívali, protože doba provádění je velmi významná, ale musí pokračovat v práci. Proto se museli dostat jiným způsobem - vybrali si v seznamech, pokusili se najít první znaky atd.

To však vede k nespokojenosti s funkčností a nesprávným vnímáním systému. Uživatel chápe, že systém se s něčím nedokáže vyrovnat a nefunguje podle očekávání. Není to správné.

Netriviální přístup k řešení problému vyhledávání podřetězců

Pojďme se nyní zamyslet netriviální přístup k řešení tohoto problému.

Pojďme určit řadu tolerancí:

  • První je proto moderní disky jsou neomezené, řekněme, že máte na disku spoustu místa, které můžete použít.
  • Druhý - uživatel nehledá podle jednoho nebo dvou znaků, ale podle nějakého fragmentu... Například nikdo z nás nehledá výraz „al“ - to je příliš malá selektivita. Hledáte nějaký smysluplný sled znaků. Zde jsme jako příklad vybrali vyhledávání podle šesti znaků.

Příklad požadovaného řetězce „alexa“ byl zapsán do formuláře a bude s ním testován.

  • Předpokládejme, že máme pole s příjmením, křestním jménem a příjmením klienta. Prvním krokem je automatické rozložení této hodnoty na fragmenty šesti znaků s posunem „1“a dostaneme řadu fragmentů (viz výše), které současně vždy patří k požadované hodnotě. Máme úryvky, které může uživatel teoreticky zadat. Konkrétně na posledním snímku bylo zjištěno, že hledáme šest znaků. Může jich být pět nebo čtyři, jen bude větší velikost konstrukce.

  • Ve druhém kroku jsme zapíšeme tyto sady do samostatné struktury (může to být tabulka, informační registr atd.) a dostaneme výběr, ve kterém určitý fragment patří k různým hodnotám.

  • A ve třetím kroku při hledání pomocí podřetězce přidáme další podmínku AND do konstrukce dotazu 1C "LIKE", která filtruje počet možných kombinací, a vytáhneme z této dodatečné struktury (může to být registr informací) všechny prvky, ke kterým patří nezbytné fragmenty, řádky.

Uživatel například hledá zákazníka s příjmením „Vojáci“. Toto je osm znaků, což znamená, že budou existovat tři fragmenty o délce šesti znaků, které hledáme ve struktuře služby. Dále to vše kombinujeme v požadavku. Tím se získá další filtrování.

Ve výsledku se zbavíme znaménka „%“ (to znamená, že tyto fragmenty budou mít vždy před sebou znak, který potřebujeme) a při provádění interního dotazu přejde Hledání indexu, za které jsme bojovali.

V praxi se ukáže velmi zajímavý příběh - zrychlení desítky, stokrát... To vše lze navíc provést pomocí 1C, což je velmi pěkné. Není třeba přepisovat logiku, uživatel bude rád, že jeho vyhledávací dotaz je rychlejší. V příkladu zrychlení ze 4 sekund na 0,05 sekundy a pokud bychom zpočátku měli požadavek spuštěný na dvě minuty, začal by se provádět za méně než sekundu.

Mechanismus, který jsem vám ukázal, není nějaký experimentální příklad, funguje již se skutečnými zákazníky.

Přípravné činnosti k provádění

Nyní krátce promluvím o přípravných činnostech.

  • Nejprve je nutné vyplnit registr počátečními hodnotami... K tomu musíme naplánovat naplánované okno.
  • Dále musíme dodržovat konzistenci dat - to znamená pro změnu hodnoty musí existovat předplatnétakže se tyto fragmenty automaticky přestaví.
  • A poslední - přidat standardní vyhledávací formulář.

Vyplňování registrů lze provádět jak pomocí 1C, tak pomocí SQL.

Mohu říci, že vyplnění takové struktury pro 17 milionů hodnot trvá asi 20-25 minut. Přirozeně by uživatelé v tuto chvíli neměli měnit hodnoty vyhledávání.

Pokud spočítáme pro jeden milion hodnot někde kolem 100 znaků o 6 ve fragmentu, dostaneme někde 4,7 GB. Musíte si naplánovat, abyste měli toto místo. Pokud máte v adresáři například 100 milionů hodnot, musíte naplánovat místo, které bude na disku k dispozici.

Nutnost zohlednit statistiky popularity fragmentů

Bude tato metoda vždy fungovat rychle?

To je ovlivněno statistiky popularity fragmentů.

  • Například máte fragment „alexe“, který lze zahrnout do jména Aleksey, do prostředního jména Alekseevich, do příjmení Alekseenko atd. Tento fragment lze zahrnout do 50–100 tisíc záznamů.
  • A tam jsou zřídka použité fragmenty.

Objevují se tedy statistiky popularity podle fragmentů.

Všimněte si, že pokud je popularita fragmentů nízká (100 prvků), dostaneme zrychlení 0,1 sekundy.

Pokud je podřetězec dostatečně populární (50 tisíc prvků), dojde k degradaci, a mnohem více, než kdyby neexistovala optimalizace.

Takto, musíte vytvořit vylepšené schéma provádění dotazůve kterém bychom nejprve získali popularitu poddotazu. To se děje ve třech až pěti řádcích v 1C. Zároveň víme jistě, že pokud je linka nepopulární, následuje první větev, a pokud je populární, pak druhou.

Jak funguje zrychlení? Z formuláře je požadavek na vyhledávání, pak se obrátíme na registr informací se statistikami, získáme prvek a poté vybereme, co použít - klasický nebo zrychlený požadavek.

Pojďme se nyní podívat na to, jak se SQL dotaz provádí na serveru SQL.

Na snímku je znázorněno zjednodušené schéma:

  • existuje požadavek na optimalizátor;
  • podíváme se na statistiky polí, která jsou použita v požadavku;
  • zvolíme, který plán provádění použít, tj. zvolíme strategii provádění dotazu (například vnořenou smyčku).

Jak vypadá obvod, který jsme implementovali?

  • Vyrobili jsme naše index... Ne standardní index SQL, ne index 1C, ale váš vlastní index, který je potřebný k vyřešení tohoto problému;
  • Navíc se potýkají s tím, že potřebují vlastní statistika;
  • A ty potřebuješ svůj vlastní optimalizátor, která pomocí těchto statistik rozhoduje, kterou větev zvolit.

Na základě této logiky můžeme říci, že tento proces odhaluje význam toho, co potřebujeme, indexy, statistiky a optimalizátor.

Kdo nevěděl, proč je třeba zobrazovat statistiky v SQL, podívejte se na tuto logiku a pochopíte, že pokud je nesprávná nebo irelevantní, přejdeme do nesprávné pobočky. Požadavek se zpomalí. Chápeme, proč musíme poskytovat statistiky efektivně a správně - to ovlivňuje výkon, index.

Pokud neexistuje žádný index, prohledáme všechny hodnoty.

Vytvořili jsme tedy alespoň primitivní, ale náš vlastní optimalizátor. Dá se říci, že cítili „na prstech“, jak to MS SQL a další DBMS dělají, a vytvořili si vlastní struktury.

Urychlení "velkých" dokumentů

Přechod na druhé téma - zrychlení velkých dokumentů.

Ve výrobních úkolech se často setkáváme s nějakými rutinními postupy, jako je uzavření měsíce, hlášení agentovi, výpočet nákladové ceny. Dokončení a dokončení těchto těžkých a rozsáhlých dokumentů trvá značně dlouho. A když se podíváme do debuggeru a sledujeme tyto operace, vidíme to 1C vkládá hodnoty řádek po řádku do tabulky a zabere to většinu času... A s tím se nedá nic dělat. Jediným doporučením, které lze nabídnout, je zrychlení disku (účinnost tohoto řešení je velmi sporná a vyžaduje předběžnou analýzu).

Navrhuji vrátit se do historie a zvážit, jak se to stalo v 1C, od 8,0 do 8,3 - to bylo provedeno řádek po řádku... Server SQL pokaždé analyzoval požadavek, zpracoval jej, vytvořil plán provádění, přidal jej, poslal příkaz směrem k 1C o úspěchu a obdržel další požadavek. A takové krok za krokem byly zaslány požadavky z aplikačního serveru 1C na MS SQL.

Je jasné, že pokud máte v dokumentu 40 záznamů, nemělo by dojít k žádným problémům. Pokud máte 10 tisíc nebo více záznamů (existují organizace, kde je v regulačních dokumentech milion záznamů), pak tento proces trvá velmi dlouho. Jeden záznam je zpracován velmi rychle, ale v dokumentu je jich příliš mnoho. Jaké jsou režijní náklady? Do sítě, k provedení požadavku, ke zpětnému signálu, ke zpracování tohoto signálu v systému 1C - celkem, součet čtyř stupňů. Všechny fáze jsou sečteny, vynásobeny milionem řádků a dostáváme naše dlouhá očekávání. Je jasné, že to není hrozné.

V 1C, počínaje verzí 8.3, byla provedena vylepšení. Nyní je na serveru SQL připraven dotaz pro vložení do dočasných tabulek a informačních registrů a jeho další provádění je prováděno pomocí klasických RPC volání, kde samotný poskytovatel přístupu 1C (nativní nebo OLE DB) seskupuje záznamy a vkládá je pomocí N řádků (obvykle 100 řádků).

Tím je dosaženo zrychlení o 30% až 300%. Ale to stále nestačí, protože dnes máte 10 tisíc řádků, zítra 20 tisíc řádků. Nejedná se o zásadní řešení problému, budete mu stále čelit, ale pouze za šest měsíců / rok.

Co nejrychlejší vložka na server SQL nebo na jakýkoli DBMS?

to HROMADNÁ VLOŽKA... V 1C se používá BULK INSERT, ale pro jiné úkoly. Také bych chtěl urychlit práci s „velkými“ dokumenty zvětšením INSERT vložek a přidáním záznamů v jednom poli do databáze serveru SQL.

Podívejme se, jakého efektu je dosaženo. V uvažovaném příkladu zrychlení je asi 5krát, ale můžete zrychlit 10krát... Teoreticky je hlavním problémem tohoto podstatně větší akcelerace rychlost disku. Disk může být překážkou.

Taky je důležité pamatovat na takové kritérium jako indexy... Pokud bychom měli vložit BULK INSERT do tabulky bez aktualizace indexů, pak bychom dostali významné zrychlení (výsledky za méně než sekundu). Tady dostaneme 69 sekund kvůli tomu, že každá příloha v tabulce vyžaduje index REFRESH.

V každém případě tato metoda umožňuje dosáhnout účinku 5-10krát.

Navíc zde nejsou brány v úvahu funkce jako rozdělení na oddíly, rozdělení. Situaci by bylo možné vylepšit, kdybychom věděli, že BULK INSERT je vložen v aktuálním období, a přesunuli bychom irelevantní do jiného oddílu. Bylo by to ještě efektivnější. Ukazuje se, že zrychlení je velmi dobré.

Možnosti optimalizace jsou nekonečné

Takto, možnosti optimalizace jsou nekonečné... Jedinou věcí je nenechat se unést. Před optimalizací má vždy smysl vypočítat, zda zamýšlený efekt bude nebo nebude. Také bych doporučil v některých situacích „povznést se“ nad problém, nepoužívat klasické metody optimalizace dotazů, ale některé zcela odlišné, které mohou přinést významnější výsledky.

****************

Tento článek byl napsán na základě výsledků zprávy () přečtené na konferenci INFOSTART EVENT 2017 COMMUNITY.

Řetězce v 1C 8.3 ve vestavěném jazyce 1C jsou hodnoty primitivního typu Čára... Hodnoty tohoto typu obsahují řetězec Unicode libovolné délky. Proměnné typu řetězce jsou sada znaků uzavřených do uvozovek.

Příklad 1. Vytvořme řetězcovou proměnnou s textem.

StringVariable \u003d "Ahoj světe!";

Funkce pro práci s řetězci v 1c 8.3

Tato část obsahuje hlavní funkce, které umožňují měnit řádky v 1c nebo analyzovat informace v nich obsažené.

Délka Str

StrLength (<Строка>) ... Vrátí počet znaků obsažených v řetězci předaném v parametru.

Příklad 2. Počítáme počet znaků v řádku „Hello world!“

String \u003d "Ahoj světe!"; Počet znaků \u003d StrLength (řetězec); Zpráva (počet znaků);

Výsledkem spuštění tohoto kódu bude zobrazení počtu znaků v řetězci: 11.

Zkratka

AbbrL (<Строка>) ... Zkrátí nevýznamné znaky nalevo od prvního významného znaku v řetězci.
Vedlejší postavy:

  • prostor;
  • neporušený prostor;
  • tabelace;
  • návrat vozíku;
  • překlad řádků;
  • překlad formuláře (stránky).

Příklad 3. Odstraňte všechny mezery z levé strany řádku „svět!“ a připojte k němu řetězec „Hello“.

Řetězec \u003d zkráceně („mír!“); String \u003d "Hello" + String; Zpráva (řetězec);

Výsledkem provedení tohoto kódu bude výstup řádku „Hello world!“

Zkratka

Zkratka (<Строка>) ... Zkrátí nevýznamné znaky napravo od prvního významného znaku v řetězci.

Příklad 4. Formulář „Hello“ a „World!“ fráze "Hello world!"

String \u003d abbreviated ("Hello") + "" + abbreviated ("world!"); Zpráva (řetězec);

SokrLP

SocrLP (<Строка>) ... Zkrátí nevýznamné znaky napravo od prvního významného znaku v řetězci a také ořízne nevýznamné znaky nalevo od prvního významného znaku v řetězci. Tato funkce se používá častěji než předchozí dvě, protože je všestrannější.

Příklad 5. Odstraňte nevýznamné znaky vlevo a vpravo na jméno protistrany.

Protistrana \u003d Directories.Contractors.NaytiPoRequisite ("INN", "0777121211"); CounterpartyObject \u003d Counterparty.GetObject (); CounterpartyObject.Name \u003d ShortLP (CounterpartyObject.Name); CounterpartyObject.Write ();

Lev

Lev(<Строка>, <ЧислоСимволов>) ... Získá první znaky řetězce, počet znaků je uveden v parametru Počet znaků.

Příklad 6. Nechte strukturu Zaměstnanec obsahovat jméno, příjmení a příjmení zaměstnance. Získejte řetězec s příjmením a iniciálami.

InitialName \u003d Leo (Employee.Name, 1); Patronymic Initial \u003d Leo (zaměstnanec, Patronymic, 1); CeléJméno \u003d Zaměstnanec.Příjmení + "" + PočátečníJméno + "." + Initial of Patronymic + ".";

Že jo

Že jo (<Строка>, <ЧислоСимволов>) ... Získá poslední znaky řetězce, počet znaků je uveden v parametru Počet znaků. Pokud zadaný počet znaků přesáhne délku řetězce, je vrácen celý řetězec.

Příklad 7. Předpokládejme, že konec řetězcové proměnné obsahuje datum ve formátu „rrrrmmdd“, získejte řetězec s datem a převeďte jej na typ datum.

String \u003d "Aktuální datum: 20170910"; StringDate \u003d Right (String, 8); Datum \u003d Datum (StringDate);

středa

Středa (<Строка>, <НачальныйНомер>, <ЧислоСимволов>) ... Získá podřetězec z řetězce předaného jako parametr Čára, počínaje znakem, jehož číslo je uvedeno v parametru Počáteční číslo a délka předaná parametru Počet znaků.Číslování znaků v řádku začíná od 1. Je-li parametr Počáteční číslo je zadána hodnota, která je menší nebo rovna nule, pak parametr nabývá hodnoty 1. Pokud je parametr Počet symbolů není zadán, jsou vybrány znaky až do konce řádku.

Příklad 8. Předpokládejme, že řetězcová proměnná počínaje od deváté pozice obsahuje kód oblasti, měli byste ji získat a napsat do samostatného řádku.

Řádek \u003d "Region: 99 Moskva"; Region \u003d St (linka, 9, 2);

Vyhledávání

Vyhledávání (<Строка>, <ПодстрокаПоиска>, <НаправлениеПоиска>, <НачальнаяПозиция>, <НомерВхождения>) ... Vyhledá zadaný podřetězec v řetězci a vrátí číslo pozice prvního znaku nalezeného podřetězce. Zvažte parametry této funkce:

  • Čára... Zdrojový řetězec;
  • Hledání podřetězce... Hledání podřetězce;
  • Směr vyhledávání... Určuje směr hledání podřetězce v řetězci. Může nabývat hodnot:
    • Směr vyhledávání. Od začátku;
    • Směr vyhledávání.;
  • Počáteční pozice... Určuje pozici v řetězci, od kterého začíná hledání;
  • Počet vstupů... Určuje počet výskytů požadovaného podřetězce v původním řetězci.

Příklad 9. V řádku „Hello world!“ určit polohu posledního výskytu symbolu „a“.

PositionNumber \u003d StrFind ("Hello world!", "And", DirectionSearch.End); Zpráva (číslo pozice);

Výsledkem tohoto provedení kódu bude zobrazení čísla posledního výskytu symbolu „a“: 9.

VReg

BReg (<Строка>) ... Převede všechny znaky v zadaném řetězci za 1 s 8 na velká písmena.

Příklad 10. Převést řetězec „ahoj svět!“ na velká písmena.

StringBreg \u003d BReg ("ahoj svět!"); Zpráva (StringVreg);

Výsledkem provedení tohoto kódu bude zobrazení řádku „AHOJ SVĚT!“

Nreg

HPreg (<Строка>) ... Převede všechny znaky zadaného řetězce za 1 s 8 na malá písmena.

Příklad 11. Převést řetězec „AHOJ SVĚT!“ malá písmena.

StringNreg \u003d НReg ("AHOJ SVĚT!"); Zpráva (StringVreg);

Výsledkem provedení tohoto kódu bude výstup řádku „ahoj svět!“

Treg

Treg (<Строка>) ... Převede řetězec následujícím způsobem: první znak každého slova se převede na velká písmena, zbývající znaky slova se převedou na malá písmena.

Příklad 12. Počáteční písmena slov v řetězci "ahoj svět!"

StringTreg \u003d Treg ("ahoj svět!"); Report (StringTreg);

Výsledkem spuštění tohoto kódu bude výstup řádku „Hello World!“

Symbol

Symbol(<КодСимвола>) ... Získá znak podle kódu Unicod.

Příklad 13. Přidejte vlevo a vpravo do řádku „Hello World!“ symbol ★

StringWithStars \u003d Symbol ("9733") + "Hello World!" + Symbol ("9733"); Report (StringWithStars);

Výsledkem tohoto provedení kódu bude výstup řádku „★ Hello World! ★“

Kód symbolu

SymbolCode (<Строка>, <НомерСимвола>) ... Získá kód znaku Unicode z řetězce určeného v prvním parametru, který se nachází na pozici určené v druhém parametru.

Příklad 14. Zjistěte kód posledního znaku v „Hello World!“

String \u003d "Hello World!"; CharacterCode \u003d CharacterCode (String, StrLength (String)); Zpráva (SymbolCode);

Výsledkem provedení tohoto kódu bude zobrazení kódu symbolu „!“ - 33.

Prázdný řádek

Prázdný řádek (<Строка>) ... Zkontroluje, zda řetězec obsahuje pouze nevýznamné znaky, to znamená, že je prázdný.

Příklad 15. Zkontrolujte, zda je řetězec skládající se ze tří mezer prázdný.

Empty \u003d EmptyString (""); Zpráva (prázdná);

Výsledkem provedení tohoto kódu bude zobrazení slova „Ano“ (řetězcové vyjádření logické hodnoty Skutečný).

PageReplace

Nahradit (<Строка>, <ПодстрокаПоиска>, <ПодстрокаЗамены>) ... Vyhledá všechny výskyty vyhledávacího podřetězce v původním řetězci a nahradí jej náhradním podřetězcem.

Příklad 16. V řádku „Hello World!“ nahraďte slovo „Mír“ slovem „Přátelé“.

String \u003d StrReplace ("Hello World!", "World", "Friends"); Zpráva (řetězec);

Výsledkem provedení tohoto kódu bude zobrazení řádku „Ahoj přátelé!“

StrNumberStrings

RowNumber (<Строка>) ... Spočítá počet řádků ve víceřádkovém řetězci. Chcete-li přejít na nový řádek za 1 s 8, použijte znak PS (znak posunu řádku).

Příklad 17. Určete počet řádků v textu:
"První řada
Druhý řádek
Třetí řádek "

Number \u003d StrNumberStrings ("První řádek" + Symbols.PS + "Druhý řádek" + Symbols.PS + "Třetí řádek"); Zpráva (číslo);

Výsledkem provedení tohoto kódu bude zobrazení počtu řádků v textu: 3

StrGetString

StrGetString (<Строка>, <НомерСтроки>) ... Získá řetězec ve víceřádkovém řetězci podle jeho čísla. Číslování řádků začíná na 1.

Příklad 18. Získejte poslední řádek v textu:
"První řada
Druhý řádek
Třetí řádek "

Text \u003d "První řádek" + Symbols.PS + "Druhý řádek" + Symbols.PS + "Třetí řádek"; LastString \u003d StrGetString (Text, StrNumberLines (Text)); Report (LastString);

Výsledkem provedení tohoto kódu bude zobrazení řádku „Třetí řádek“.

Str Počet událostí

Str Počet událostí (<Строка>, <ПодстрокаПоиска>) ... Vrátí počet výskytů zadaného podřetězce v řetězci. Tato funkce rozlišuje velká a malá písmena.

Příklad 19. Určete, kolikrát se písmeno „c“ objeví v řádku „Řádky za 1 s 8.3 a 8.2“, bez ohledu na jeho velikost.

Line \u003d "Lines in 1s 8.3 and 8.2"; Number of Occurrences \u003d StrNumber of Occurrences (Vreg (String), "S"); Zpráva (počet výskytů);

Výsledkem spuštění tohoto kódu bude zobrazení počtu výskytů: 2.

Stránka začíná s

PageStarts With (<Строка>, <СтрокаПоиска>) ... Zkontroluje, zda řetězec předaný v prvním parametru začíná řetězcem ve druhém parametru.

Příklad 20. Určete, zda TIN vybrané protistrany začíná číslem 1. Nechte proměnnou Protistrana Dodavatelé.

TIN \u003d Counterparty.INN; StartsUnits \u003d StrStartsWith (INN, "1"); If BeginsUnits Then // Váš kód EndIf;

Stránka končí

PageEnds With (<Строка>, <СтрокаПоиска>) ... Zkontroluje, zda řetězec předaný v prvním parametru končí řetězcem ve druhém parametru.

Příklad 21. Určete, zda TIN vybrané protistrany končí číslicí 2. Nechte proměnnou Protistranaje uložen odkaz na položku adresáře Dodavatelé.

TIN \u003d Counterparty.INN; Končí dvěma \u003d Str končí (INN, „2“); If Ends With Double Then // Váš kód EndIf;

PageSplit

StrSplit (<Строка>, <Разделитель>, <ВключатьПустые>) ... Rozdělí řetězec na části pomocí zadaných znaků oddělovače a zapíše výsledné řetězce do pole. První parametr ukládá původní řetězec, druhý obsahuje řádek obsahující oddělovač, třetí označuje, zda by se do pole měly zapisovat prázdné řetězce (standardně Skutečný).

Příklad 22. Předpokládejme, že máme řetězec obsahující čísla oddělená znakem „;“, získáme z řetězce pole čísel.

Řetězec \u003d "1; 2; 3"; Array \u003d StrSplit (String, ";"); Pro RV \u003d 0 podle pole.Quantity () - pole pokusu o 1 cyklus [Rd] \u003d číslo (AbbrLP (pole [Rd])); Pole výjimek [Сч] \u003d 0; Konec pokusů Konec smyčky;

V důsledku provedení bude získáno pole s čísly od 1 do 3.

StrConnect

StrConnect (<Строки>, <Разделитель>) ... Převede pole řetězců z prvního parametru na řetězec obsahující všechny prvky pole, oddělené oddělovačem uvedeným v druhém parametru.

Příklad 23. Pomocí pole čísel z předchozího příkladu získáte původní řetězec.

For Ref \u003d 0 Array.Quantity () - 1 Loop Array [Ref] \u003d String (Array [Ref]); Konec cyklu; Řetězec \u003d StrConnect (pole, ";");