
Más recientemente, publicamos
un artículo que describe los problemas de una de las tecnologías más populares utilizadas en TI, y para nuestra sorpresa, despertó un interés bastante vivo (al menos para un artículo técnico). Por lo tanto, decidimos no detenernos allí, y hoy vamos a "visitar" uno de los productos más populares en el mercado ruso para desarrollar aplicaciones comerciales: la plataforma 1C.
Dio la casualidad de que a muchos 1Cs no les gusta el hub, pero a veces parece que pocas de estas personas entienden bien, por lo que no les gusta. Con este artículo, llenamos este vacío y matamos dos pájaros de un tiro: por un lado, le diremos cómo funciona todo en 1C desde adentro y, por otro lado, por qué no funciona de la manera que desea / quisiera. Debo decir que 1C con muchas de sus decisiones realmente podría sorprendernos, sin embargo, no nos adelantaremos.
Hay suficientes artículos que critican a 1C en Habré (por ejemplo,
uno ,
dos ,
tres ), pero, en mi opinión, prestan demasiada atención a todas las pequeñas cosas, como que el menú está incorrectamente organizado, o hablan de cosas demasiado abstractas en las que posiblemente 1C es y no tiene la culpa. En el mismo artículo, así como en el artículo sobre SQL, nos enfocaremos exclusivamente en problemas fundamentales (y bastante tangibles) que conciernen a todos y cada uno que desarrolla / refina soluciones en 1C, y conduce a un aumento significativo en el umbral de entrada o a un una caída en la productividad o costos laborales significativos por parte del desarrollador.
Entonces vamos. Hay muchos problemas en 1C, por lo tanto, para que sea más conveniente navegar, comenzamos con una tabla de contenido (con una lista de todos estos problemas):
Traté de construir las secciones en orden de conceptos básicos / problemas a los más complejos, aunque de hecho en su mayor parte no están conectados entre sí. Por lo tanto, si alguien es demasiado vago para leer el artículo completo, puede leer las secciones individuales de su interés de la tabla de contenido, prácticamente no hay una trama transversal.
Objetos: directorios, documentos, etc.
¿Cómo se organizan generalmente los marcos / plataformas ORM? En el lenguaje de desarrollo del marco ORM, las clases de objetos son compatibles de una forma u otra. Para cada una de estas clases, el desarrollador puede especificar su asignación a alguna tabla. Como regla, una clase corresponde a una tabla, cuya única clave, a su vez, corresponde al identificador de un objeto de esta clase. Aquí, por supuesto, surge la pregunta de qué hacer con las tablas que tienen varias claves. Las clases correspondientes también se crean para ellos, ya que la mayoría de los ORM admiten varios campos de la misma clase que los identificadores. A veces, por supuesto, con tal mapeo, obtenemos abstracciones bastante completas como CommodityWarehouse, pero en la mayoría de los casos los datos se manejan en el mismo paradigma (OOP).
En 1C, decidieron ir a otro lado y apoyar ambos paradigmas a la vez, simultáneamente tienen objetos y registros. La lógica de los registros es utilizada por registros y consultas (sobre ellos en las siguientes secciones), la lógica de los objetos se asemeja a un ORM regular, sin embargo, con sus propias características:
- El desarrollador no controla la visualización en las tablas y, en general, está oculto (aunque no tiene nada de especial)
- No hay asignaciones de uno a muchos, de muchos a muchos; su función es realizada por las llamadas partes tabulares, colecciones de objetos internos que en realidad se agregan al objeto principal.
Recuperación ineficiente de los datos del objeto.
Dado que la lectura prematura o excesiva de los datos del servidor de bases de datos y transferirlos al servidor de aplicaciones puede conducir a una caída significativa en el rendimiento, por lo general, los marcos ORM proporcionan al desarrollador un conjunto completo de herramientas para administrar los datos que reciben. Pero no 1C. En 1C, un objeto siempre se lee en su totalidad, incluso con partes tabulares, pero no más (sin ningún dato asociado). Como resultado, los datos se leen:
- o demasiado, si necesita obtener solo un campo (accesorios)
- o muy poco: si en el ciclo necesita acceder a otros objetos por referencia, obtenemos el clásico problema N + 1 (una solicitud para obtener N objetos y una solicitud para cada enlace).
Tal desgracia del mecanismo ORM en 1C en realidad se debe al hecho de que en 1C, en algún momento, simplemente decidieron abandonar ORM y confiar en SQL simple (es decir, registros y consultas). Es cierto que, mirando hacia el futuro, dada la falta de características avanzadas de SQL y DML en 1C, periódicamente regresan a ORM, pero esto es más bien una necesidad necesaria. Pero en general, un código típico de soluciones típicas en 1C se parece a esto:
Ejemplo de código (, , = )
////////////////////////////////////////////////////////////////////////////
//
= ;
(, );
////////////////////////////////////////////////////////////////////////////
//
= ;
(, , );
(, , );
(, , );
(, , );
(, , );
(, , );
(, , );
(, , );
(, , );
(, , );
(, , );
(, , );
(, , );
(, , );
(, , );
(, , );
0(, , );
(, , );
(, , );
(, , );
(, , );
(, , );
.(, , ., );
(, , )
= "";
.(, )
"";
;
=
"
| (.) ,
| & ,
| . ,
| . ,
| . ,
|
| . (10, 14)
| .
| (..)
| ,
| . ,
|
| .. ((..), (..))
| .
| (..)
| ,
| 0 ,
| . ,
| .
|
| ..
|
| . = &
| . <> 0
| & <> (..)
| &
| &
|
|
|
|
| (.),
| &,
| .,
| .,
| .,
|
| . (10, 14)
| .
| (..)
| ,
| .,
|
| .. ((..), (..))
| .
| (..)
| ,
| .,
| .,
| .
|
| ..
|
| . = &
| . <> 0
| & = (..)
| &
| &
|
|
|
|
| (.),
| &,
| .,
| .,
| .,
|
| . (10, 14)
| .
| (..)
| ,
| .,
|
| .. ((..), (..))
| .
| (..)
| ,
| 0,
| .,
| .
|
| ..
|
| . = &
| . = 0
| &
| &
|
|
|
|
| (.),
| &,
| .,
| .,
| .,
|
| . (10, 14)
| .
| (..)
| ,
| .,
|
| .. ((..), (..))
| .
| (..)
| ,
| 0,
| .,
| .
|
| ..
|
| . = &
| . = 0
| &
| &";
.(, );
;
/ :
1 , :
- . — , — , () ( )
— ERP- 1 . , SQL ( ), , — , . 1 , , , . — . ( 1 ).
1 :
SQL, , 1 ( )
SQL.
, 1 : , . , MS SQL, Oracle. , , — ( / ) () .
( ), SQL : 1 , , / , / , ( ).
1 , , . , , 0, - . SQL , 1 . ? , , :
( SQL per-statement trigger on before) :
// ,
// .
= ;
.("", ..);
. = ...;
. =
"
| . ,
| . ,
| . ,
| . ,
| . ,
| . ,
| . ,
| . ,
|
| . = (.)
| . + .
| -. - .
| ,
|
| . = (.)
| .
| -.
| ,
|
| . = (.)
| -.
| .
| ,
|
| . = (.)
| -.
| .
|
|
|
| .
|
| . = &";
.();
(on after) + :
= ..;
= ;
= ..() = ..;
.("", );
.("", ..);
. = .;
//
// .
. =
"
| . ,
| . ,
| . ,
| . ,
| . ,
| . ,
| . ,
| (.) ,
| (.) ,
| (.)
|
|
| (
| . ,
| . ,
| . ,
| . ,
| . ,
| . ,
| . ,
| . ,
| . ,
| . ,
| .
|
|
|
|
|
|
| .,
| .,
| .,
| .,
| .,
| .,
| .,
| .,
|
| . = (.)
| -.
| .
| ,
|
| . = (.)
| .
| -.
| ,
|
| . = (.)
| .
| -.
|
|
| .
|
| . = &)
|
|
| .,
| .,
| .,
| .,
| .,
| .,
| .,
| .
|
|
| ((.) > 0
| (.) > 0
| (.) > 0)
|;
|
|////////////////////////////////////////////////////////////////////////////////
|
| . ,
| . ,
| . ,
| . ,
| . ,
| . ,
| (.)
|
|
| (
| . ,
| . ,
| . ,
| . ,
| . ,
| . ,
| . ,
| -.
|
|
|
| . <> (..)
| ..
|
|
|
|
| .,
| .,
| .,
| .,
| .,
| .,
| .,
|
| . = (.)
| . + .
| -. - .
|
|
| .
|
| . = &)
|
| . <> (..)
| ..
|
|
| .,
| .,
| .,
| .,
| .,
| .,
| .
|
|
| (.) > 0
|;
|
|////////////////////////////////////////////////////////////////////////////////
| ";
= .();
= [0].();
.();
// .
// .
.("", . > 0);
= [1].();
.();
.("", . > 0);
( ) , 0.
(,"")
.((""));
= +
"
|
| . ,
| .. ,
| . ,
| . ,
| . ,
| . ,
| (.)
|
|
|(
| . ,
| . ,
| . ,
| . ,
| . ,
| -. - .
|
| ..(
| ,
| (, , , , )
| (
| .,
| .,
| .,
| .,
| .
|
| ))
|
|
|
| . ,
| . ,
| . ,
| . ,
| . ,
| .
|
| ..(
| ,
| (, , , , )
| (
| .,
| .,
| .,
| .,
| .
|
| ))
|)
|
|
| .,
| .,
| .,
| .,
| .
|
|
| (.) < 0
|;
|///////////////////////////////////////////////////////////////////
|";
;
PS: , , .
( ), 1 ( ). 1 , .
SQL . , :
= ;
. =
"
| . ,
| . ,
| .
|
| .
| ..(., = .)
| . = .
| . = & "
;
= .();
2 : “ ” “ ”. - IN () ( 1, ), , , , , , — . SQL JOIN — LATERAL JOIN APPLY, 1 . , , , , . / . , .
, , , 1 , . 1 , , , . , (OLTP) , ( ), (, , , ).
1 SQL, SQL. , , SQL, 1 , .
( ). :
, , 1 (C, ), ( ). , 1 . - , , .
1 — SQL- 1 , . . , (MS SQL, Oracle), 1 PostgreSQL, « , ». ,
, PostgreSQL Join Predicate Push Down ( ). 1 , .
1 — ( , ). . ,
:
, - , ( , ). , .
1 « », . « » . . - , . ().
:
.,
.
..
..(,
(
..
= &))
. = .
. = &
(. < .
. NULL)
, , 1
, « » , , PostgreSQL, ( IN / EXISTS PostgreSQL ). , , , ( ).
SQL
, SQL 1 , , , . , - , CTE, 1 , . , , , , 1 , SQL- 1 SQL 92. , ,
( ), ORM, , , 1 .
, . , SQL, 1 ( DML), . , , ORM ( ) .
SQL ( CI ACID). ( ). , , , - , . , , , .
. , , . , , «» . (MVCC) Oracle PostgreSQL -, , .
, . , , , , ( , ), , . ? , ( ). , «» , :
- , . , , , , , SQL ( ), 1, .
- , , «» , FOR UPDATE ( ).
, , , ( ), , ( ).
1. ? . . ( ). . , . , - . — .
, «» 1 . , , / , , , .
ERP , , , . 1 . 1 Access, .
:
. - , , ( , ), . — ( -, ) , . ( ), — .
1? , , — . , , , — , , .. ( , ). :
. myForm otherForm, ( , ) .
, , 1 , , . / . :
- ( ). & 1 . , ( ), .
- «» ( Java EE) . , .
- ( , , windows ) , . ( )
, , . , 1 , . , (, ), ( ). - - , . . , , , , 1 () , , :
, , , 1 - .
? , , , ? , - , , . 1 - .
:
, . , , .
, - .
1 . , , - , . - :
&
()
= ("", );
();
&
(, )
();
&
()
= ("", );
= ("", , );
(, " ?", .);
&
(, )
= ?( = .,
" ...",
" !");
<> . <>
(., );
;
WYSIWYG:
/ WYSIWYG. , , , 1 , WYSIWYG , 1 .
1 . :
, , , ( ). 1 — , . , , , :
/
, , , . , / 1 , .
, , , :
. « » , .
, ( ) — 1 (, , ).
, , 1 , . , , , , , , .
1, , 1 , - . , , 1 , . :

: ? , , , , , 1, , .
- /
ORM. , ( ), , 1 , (), . , , 1 .
- /
, . , / C#, C++. . , , — . — - ( ), ( ) . , ( ORM, ORM) .
- /
( ) , . 1 - , (, ) (, ) . 1 , . , . , , ( ). , ( ).
, , , , . - .
1 , . , ( , ).
- / / (BI)
- : OLTP OLAP. - -: . OLAP — , «» , . OLTP , OLAP . , , OLTP - , , / , , -, ( ), -, - , . , , , ( OLAP), , .
OLAP , SQL - , . .
1 . () :
- , 1. (, ) . , , — .
1 - . , . , , , ( , , ), , ( ) , .
: OLAP , , ( , — _Fld16719 _Document5759).
1 , , 1.
, . 1, , 1 - SQL, SQL
, 1 .
, , «, , if'» . , 1, , , :
20 Foxpro ( IF TYPE(«tableA.fldB») = «C») , . , 2019 .
P.S.: 1
, .
1 . — (). , , ( , , 1 ). 1 , , . , ,
:
- , .
- , , , . , «» «» «» , :
.
.
.
. = .
- , .
- , , .
- , .
- .
, ( ). : « — ».
( , ..). . , , . IDE () - , , , , .
, , 1 . , -, , , , .
- . ( ) , , , , ( ), - , . .
1 . , -, , , . , ( ), 1 . , 1
:
, . -, , . -, , , , .
…
, .
-, — :
- , , , 1 ( -)
- , , N+1, , . 1 , (, ), , 1 .
- , , , 1
- , ,
, , , 1 . — . :
, 1 « SAP» — , : « , best practice, ». , , ( «--»). - . — . , , , :
- ( , / )
- ( : , , )
- . , ( , ), .
, low-code / no-code , . , / . — . / , . , / , , , . « , » , .
(--- vs ). , :
- — gitflow ( )
- / — / IDE
- — , , , « , » , ,
- — , , ..
- — IDE ( , , ..). .
- —
- — , / , , :
:
. , . , «», «» . , , «» , «» , ? , , .
1. , 1 EDT, « ». language-based, 1 , , XML.
. XML , :
- ( , ). ( ) 1336 .
- id, , , , .
/ — . ---, 1, . , , , .
, Microsoft 1, . , 1 , :
- IDE — IDEA, Eclipse, Microsoft Visual Studio / VSCode . IDEA , .
- — git , subversion mercurial . 1 git, , .
- — / , PostgreSQL, . , , 1 - SQL-92 , .
PostgreSQL, ( , 1 ), . .
- — , , . 1 - ( ) BI. 1 , .
- — 1 . , , , , ( -). language-based (, , SAP SQL, ), . 1 , . : « , , ». 1 - . , , , / — , , , callback' — .
- / — Jenkins TeamCity, Java — Maven, Gradle, JavaScript — npm, Python — pip .. community, , , IDE . 1 -, , , , , , .
- UI . , , Linux, MacOS ( Java ), , « » .
, 1 , Eclipse. , , , ( ERP) . , , Eclipse stub , (chameleon ), language injection .., IDEA ( Eclipse , , EDT ).
, EDT 1 IDE. ,
« ». , , Eclipse IDEA, 1 IDE.
1
. : 1: 8. 22 600 . (!). ? , : 1: 8 . 100 — 360 000. 1: 8.3 . — 86 400. , , (!) . , , , . , 22 600 . .
1 , , — 1 , ( ) — . , IT, : « / 1». , , : , — 1. — . , , , ( ) . :
- 1 , , , , - , ( ). : « 20 1 , ?». - , , ( ).
- , / 1 ( , , ..). , 1, - , , «1 », 1.
, IT- . , , . 1 , 1 . , , , , .
, , , 1 :
- ORM
- SQL:
- control flow
- WYSIWYG
, goto. . , «» . , , . — . , , — .
, , — , . , , . , ,
lsFusion , , ,
. .
, 1 , , (, , ) . , . , .
, : , . IT , ( ) Oracle, SAP Microsoft .
, 1 - . , . , — , , , « ». 1 , - ( «») — , , . lsFusion, , .Net+MSSQL Python+PostgreSQL . , , , . — ( , .Net) ? - : — , . IT. - ? , , , , , .
Axapta SAP. , ( 1 ), , , , , , . , , . , , , , , , , ( Axapta SAP , 1).