sábado, 12 de septiembre de 2020

Datalist Extendido

Esta funcion carga el Datalist de un textbox con un search a un folder (puede ser un keyword por ej), y agrega a esta lista los valores previamente ingresados en el mismo campo. Es decir, se va ampliando la lista con lo que se carga.

Para implementarlo creamos un Textbox enlazado a un campo, marcamos la opcion Datalist y en el ScriptBeforeRender agregamos:
DatalistExtended this, "/config/listas", "description", "type = 'Sector'"

El codigo de la funcion se recomienda incorporarlo a la biblioteca de funciones:

Sub DatalistExtended(pControl, pFolder, pField, pFormula)
	Dim sql, rcs, op, dic, fld, dom, node, newVal, i
	
	pControl.Load
	pControl.Options.RemoveAll
	
	' https://www.robvanderwoude.com/vbstech_data_sortedlist.php
	Set dic = CreateObject("System.Collections.Sortedlist")
	
	If TypeName(pFolder) = "Folder" Then
		Set fld = pFolder
	Else
		Set fld = Folder.App.Folders(CStr(pFolder))
	End If

	Set dom = fld.Search(CStr(pField), CStr(pFormula))
	For Each node In dom.documentElement.childNodes
		newVal = node.attributes(0).value
		If newVal & "" <> "" Then
			If Not dic.Contains(newVal) Then dic.Add newVal, ""
		End If
	Next

	sql = "select distinct " & pControl.DatalistField & " from SYS_FIELDS_" & pControl.DatalistFolder.Form.Id & _
		" f inner join SYS_DOCUMENTS d on f.DOC_ID = d.DOC_ID where d.FLD_ID = " & pControl.DatalistFolder.Id  & _
		" order by " & pControl.DatalistField
	Set rcs = dSession.Db.OpenRecordset(CStr(sql))
	Do While Not rcs.EOF
		newVal = rcs(pControl.DatalistField).Value
		If newVal & "" <> "" Then
			If Not dic.Contains(newVal) Then dic.Add newVal, ""
		End If
		rcs.MoveNext
	Loop
	rcs.Close

	For i = 0 To dic.Count - 1
		Set op = pControl.OptionsAdd
		op.Value = dic.GetKey(i)
	Next	
End Sub

viernes, 21 de agosto de 2020

Listar usuarios y grupos

Mediante el siguiente SQL podemos levantar la lista completa de usuarios con los grupos a los que pertenece en un solo comando:

select a.NAME, u.LOGIN, u.DISABLED, 
(select stuff((select '; ' + a2.NAME from SYS_ACCOUNTS a2 
inner join SYS_ACC_REL r on a2.ACC_ID = r.ACC_ID_PARENT 
where r.ACC_ID_CHILD = a.ACC_ID for xml path('')) , 1, 1, '')) as GROUPS 
from SYS_ACCOUNTS a inner join SYS_ACC_USERS u on a.ACC_ID = u.ACC_ID 
where a.TYPE = 1

martes, 18 de agosto de 2020

Datalist sin permisos

La funcionalidad Datalist en los controles Textbox crea una lista blanda con los valores anteriormente ingresados en el campo al que esta asociado el control (autocompletar).

Estas opciones se cargan mediante un Search, por lo que levantan solo aquellas que el usuario logueado puede leer.

Para crear un Datalist que no tenga en cuenta los permisos podemos usar la siguiente función:


Sub DatalistSinPermisos(pControl)
	Dim sql, rcs, op
	
	pControl.Load
	pControl.Options.RemoveAll
	
	sql = "select distinct " & pControl.DatalistField & " from SYS_FIELDS_" & pControl.DatalistFolder.Form.Id & _
		" f inner join SYS_DOCUMENTS d on f.DOC_ID = d.DOC_ID where d.FLD_ID = " & pControl.DatalistFolder.Id  & _
		" order by " & pControl.DatalistField
	Set rcs = dSession.Db.OpenRecordset(CStr(sql))
	Do While Not rcs.EOF
		If rcs(pControl.DatalistField).Value & "" <> "" Then
			Set op = pControl.OptionsAdd
			op.Value = rcs(pControl.DatalistField).Value
		End If
		rcs.MoveNext
	Loop
	rcs.Close
End Sub


Esta función podemos colocarla en alguna biblioteca compartida, y luego en el ScriptBeforeRender del control colocamos lo siguiente:


DatalistSinPermisos this

lunes, 17 de febrero de 2020

SplitAndGet - SQL Server

La siguiente funcion para SQL Server divide un string mediante un separador, y devuelve el item n del supuesto array (supuesto porque SQL no soporta arrays)


ALTER FUNCTION dbo.SplitAndGet (@pString NVARCHAR(MAX), @pDelimiter CHAR(1), @pIndex INT)
RETURNS NVARCHAR(MAX)
AS
BEGIN 
 DECLARE @start INT, @end INT, @ret NVARCHAR(MAX), @idx INT
 SET @start = 1
 SET @end = CHARINDEX(@pDelimiter, @pString)
 SET @idx = 0
 WHILE @start < LEN(@pString) + 1
 BEGIN 
  IF @end = 0  
   SET @end = LEN(@pString) + 1
       
  IF @idx = @pIndex
  BEGIN
   SET @ret = SUBSTRING(@pString, @start, @end - @start)
   BREAK
  END
  SET @start = @end + 1 
  SET @end = CHARINDEX(@pDelimiter, @pString, @start)
  SET @idx = @idx + 1
 END 
 RETURN @ret
END

GO

SELECT dbo.SplitAndGet('item0/item1/item2/item3', '/', 2)

miércoles, 15 de enero de 2020

IMPORT - Valores numericos se importan como NULL

Cuando importamos un Excel donde en una columna hay un mix de valores de texto y numéricos, los valores numéricos se importan como NULL.

Para salvar este problema debemos realizar la siguiente modificación a la línea 141 de la codelib IMPORT:

cnn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & pFile & ";Extended Properties=""Excel 8.0;HDR=YES;IMEX=1"""


IMPORTANTE: Ver este articulo respecto a como determina Excel el tipo de datos de una columna. 

En el articulo estan especificadas las rutas de registro para los providers de 64 bits. Para los de 32 bits la ruta es:

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Jet\4.0\Engines\Excel\

jueves, 5 de septiembre de 2019

Error en árbol de carpetas - Actualización Chrome


A partir de la actulización de la versión de Chrome 76.0.3809.132, puede que algunos usuarios experimenten un desplazamiento del árbol del carpetas de Doors al navegar por el mismo como muestra la siguiente figura:


Para corregir este inconveniente en versiones de Doors de 7.4.17 y superiores (en caso de ser anterior la versión contactarnos a info@cloudy-vision.com) se deberá proceder de la siguiente forma:

7.4.20 y superiores:
Se deberá agregar la biblioteca de código "custom_home_css" (en caso de no existir) en la carpeta Carpetas del sistema->Forms->Biblioteca de código  y agregar las siguientes lineas de código:

                              .favorites ul{
                                 height:auto;
                              }




7.4.17, 7.4.18 y 7.4.19 
Se deberá editar el archivo físico "custom_script.js" ubicado en la carpeta "<path_instalacion>\webNet\customs\js" y agregarle la siguiente línea al final del mismo:
                             $(".favorites ul").css("height","auto");

Esto corregirá el desplazamiento del árbol ante la navegación por el mismo.
Este inconveniente se encontrará resuelto en la versión 7.4.27.1