Kurro Lopez · Sep 30, 2025 go to post

if you are using Ens.Request as request class, you can redirect you message acording the name of the class using "Switch"

On each switch connector, you must evaluate the class name, as follows:

$classname(request)="MyApp.Msg.Test1"

I hope this is the answer that you are looking for

Best regads

Kurro Lopez · Apr 7, 2025 go to post

Hi @Touggourt 

If you want to retrieve the values, prepare the query by concatenating the values ​​you want to retrieve

set var1 = "Book"
set var2 = "Author"
set query = "SELECT "_var1_","_var2_" FROM myTables.Books"
set statement = ##class(%SQL.Statement).%New()

set status = statement.%Prepare(query)
set rset = statement.%Execute()
do rset.%Display()

Have a look the following link:

https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cl…

Regards
 

Kurro Lopez · Feb 9, 2024 go to post

It's not a bad idea, but the last value has very little chance of appearing

FOR I=1:1:100 {W $Piece("SAD,MED,TEN,BOB,RAN",",",$r(4)+1),"-" }

TEN-TEN-BOB-TEN-SAD-MED-MED-MED-MED-MED-TEN-MED-BOB-MED-MED-TEN-TEN-MED-SAD-BOB-MED-SAD-BOB-
TEN-TEN-BOB-BOB-SAD-BOB-TEN-MED-BOB-BOB-MED-TEN-MED-SAD-BOB-BOB-BOB-MED-MED-TEN-MED-TEN-MED-
TEN-BOB-MED-TEN-SAD-MED-MED-MED-BOB-SAD-SAD-MED-SAD-BOB-SAD-TEN-BOB-BOB-TEN-BOB-TEN-BOB-SAD-
SAD-TEN-MED-TEN-SAD-BOB-MED-SAD-SAD-BOB-MED-TEN-TEN-SAD-SAD-SAD-BOB-BOB-BOB-TEN-MED-BOB-BOB-
TEN-BOB-SAD-SAD-BOB-BOB-BOB-MED

SAD    20%
MED    27%
TEN    23%
BOB    30%
RAN    0%

I've tried to user other way, for example, using a GUID, get the checksum and get the module 5

Something like $Piece("SAD,MED,TEN,BOB,RAN",",",($ZCRC(##class(%SYSTEM.Util).CreateGUID(),0)#5) + 1)

for i=1:1:100 {W $Piece("SAD,MED,TEN,BOB,RAN",",",($ZCRC(##class(%SYSTEM.Util).CreateGUID(),0)#5) + 1),"-"}

TEN-SAD-BOB-MED-BOB-BOB-MED-MED-BOB-RAN-MED-BOB-RAN-MED-RAN-BOB-BOB-MED-RAN-SAD-RAN-MED-MED-
BOB-TEN-BOB-RAN-MED-TEN-TEN-TEN-SAD-BOB-MED-BOB-BOB-BOB-RAN-RAN-TEN-MED-RAN-RAN-BOB-RAN-TEN-
MED-TEN-TEN-MED-RAN-BOB-TEN-SAD-SAD-TEN-TEN-TEN-BOB-RAN-MED-SAD-MED-SAD-RAN-RAN-RAN-BOB-MED-
SAD-MED-RAN-RAN-SAD-RAN-RAN-BOB-MED-TEN-TEN-RAN-BOB-TEN-TEN-RAN-BOB-BOB-TEN-MED-SAD-SAD-BOB-
BOB-BOB-SAD-TEN-MED-TEN-BOB-SAD

SAD    13%
MED    20%
TEN    20%
BOB    25%
RAN    22%

I have best percentage to get a different value.

Kurro Lopez · Sep 20, 2022 go to post

Hi,

Indeed, the problem was caused because the address to which it is going to connect is variable, so the component is not configured with the Server or URL parameters.

I've solved it by the following way:

set ..Adapter.HTTPServer = pRequest.Url
Set URL = pRequest.Url_"/search"
set tHttpResponse = ##class(%Net.HttpResponse).%New()
set tSC = ..Adapter.SendFormDataArray(.tHttpResponse,"POST",tHttpRequest,,,URL)

if $$$ISERR(tSC) && (tHttpResponse="") $$$ThrowStatus(tSC)

// Check what is the status code
set content = ""
while (tHttpResponse.Data.AtEnd = 0) { 
    set content = content_tHttpResponse.Data.Read() 
}

do pResponse.%JSONImport(content)
set pResponse.StatusCode = tHttpResponse.StatusCode

Regards,
Kurro Lopez

Kurro Lopez · Apr 27, 2022 go to post

Thanks Robert but it wasn't a firewall problem.

The problem was due the instalation didn't compile the code correctly. It doesn't get the version of ISC as expected.

I'm using the version WebTerminal-v4.9.3, in the line 1507 there is a initialization of the parameter iscProductVersion

<Parameter name="iscProductVersion">
<Description>
In older Cache versions, method "GetISCProduct" does not exists</Description>
<Expression>$case(
        ##class(%Dictionary.CompiledMethod).IDKEYExists("%SYSTEM.Version", "GetISCProduct"),
        1: $CLASSMETHOD("%SYSTEM.Version", "GetISCProduct"),
        : 2
    )</Expression>
</Parameter>

Later, in line 1611, it checks what is the version to set the role required:

set requiredRole = $case(..#iscProductVersion >= 4, 1: "%DB_IRISSYS", : "%DB_CACHESYS")

But, if I check what is my version, the answer is 3, instead of 4, so it was trying to set %DB_CACHESYS instead of %DB_IRISSYS, so the compilation didn't end.

w ##class(%SYSTEM.Version).GetISCProduct() 
3

Then, I've modified the file and change the comparison  ..#iscProductVersion to check if is equal or upper than 3, and it works.

In the line 1730, there is other comparison to set the dbPrefix, so I've modified this line also.

set dbPrefix = $case(..#iscProductVersion >= 3, 1: "IRIS", : "CACHE")

Now, I have the Webterminal worning fine.

Note: I'm using IRIS for Windows (x86-64) 2021.1 (Build 215U) Wed Jun 9 2021 09:39:22 EDT

Best regards,
Francisco Lopez

Kurro Lopez · Sep 29, 2021 go to post

Hi,

The $HOROLOG is the cache datetime format, then the first part is de date and the second part is the time. The time is in seconds, then if you want to increase 15 minutes, you should to plus the time (15*60)

This is a example:

It only works if you are in the same day, because it raises an error

The best way to increase minutes, days, months, etc... is using $system.SQL.DATEADD method

https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KE…

Best regards,
Kurro

Kurro Lopez · Sep 18, 2020 go to post

I think the best approach to your goal is create a DTL and clone the message directly, then check the value of DG1:4.1 and set the value in target that you want. See below

You can call to the DTL and you'll have your new message.

Regards,
Kurro Lopez

Kurro Lopez · Sep 17, 2020 go to post

Hi,

if you read your requirements, that is that you have to write in your DTL

The first line copy all your PID in the new destination (green box)

the condition, check if the 11(1).8 has value, in this case, concatenate PID:11(1).1_PID:11(1).2 to new PID:11(1).1

I understand, when you say "move 11(1).8 to 11(1).2 means that the value in 11(1).8 will be empty (red box), if it is not the case, don't use this line.

For other case (step 7). remove the value of the PID:11(1).8

The DTL conditions are executed in order, It means, that the value in PID:11(1).2 in step 3 is the original then it is replaced by PID:11(1).8 in the following step.

This is the test result:

I hope it helps you,

Regards,

Kurro Lopez

Kurro Lopez · Sep 10, 2020 go to post

Hi Kurt,

Check if you are using ODBC 32 or 64 bits. Maybe there are two applications (one for each configuration) and not all ODBC connection are displayed.

I'm using ODBC 64 bits and my connections are availables

Also, check if your ADO .Net driver is for 32 or 64 bits compatible.

I hope it is help for you,

Regards,
Kurro

Kurro Lopez · Sep 7, 2020 go to post

Hi Tim,

I know that is a old question, and I don't know if you have resolved your problem.

I have something like you are asking in a process. Maybe it could help you.

I created a persistent class with theses properties, also add a Query to retrieve info from a ProcessId:

Class FtpFileReport Extends %Persistent
{

/// ProcessId
Property ProcessId As %String;

/// Filename
Property FileName As %String;

/// Retrieve records of a ProcessId
Query GetRecordsByProcessId(pProcessId As %String) As %SQLQuery
{
    SELECT ProcessId, FileName
    FROM FtpFileReport
    WHERE ProcessId = :pProcessId
}

}

Then, when my process start to grabs the file, create a ProcessId, for example, using a combination of horolog and cryptotoken, to create an unique Id.

set pProcessId = "ID"_$PIECE($HOROLOG,",")_$PIECE($HOROLOG,",",*)_$SYSTEM.Encryption.GenCryptToken()

For each file grabbed, you save a record in your persistent class

set obj=##class(FtpFileReport).%New()

set obj.ProcessId = pProcessId    ;pProcessId is the variable with the Id created previously

set obj.FileName =  pFileName   ;if you are using retrieveFile method, it is the name the file that is grabbing

do obj.%Save()

Afterward, create a message to a BO that send the email with the ID of the process and create the message body based on ProcessId files:

Class SendEmail Extends Ens.BusinessOperation
{

Parameter ADAPTER = "EnsLib.EMail.OutboundAdapter";

Parameter INVOCATION = "Queue";

/// Send email of FTP Report
Method SendFtpReport(pRequest As Ens.StringRequest, Output pResponse As Ens.StringResponse) As %Status
{
    #dim myList As %Library.ListOfObjects

    set report  = ##class(FtpFileReport).%New()
    set myList = ##class(%Library.ListOfObjects).%New()
    set resultset = report.GetRecordsByProcessId(pRequest.StringValue)
    set data = ##class(%Stream.GlobalCharacter).%New()
    while resultset.%Next()
    {
        set fileNum = $Increment(fileNum)
        do data.Write("<b>"_fileNum_":</b><p>"_resultset.%Get("FileName")_"</p><hr>")
        do myList.Insert(data)
    }

    set msg = ##class(%Net.MailMessage).%New()
    set msg.IsHTML = 1
    do msg.TextData.WriteLine("<h1>FileReport</h1><br><h2>This is the FTP report: <h2><br><br>")    ; This is the body of the email

    for pos=1:1:myList.Size
    {
        do msg.TextData.Write(myList.GetAt(pos).Read())
    }

    set msg.To = ##class(%Library.ListOfObjects).%New()  ;Destinations address
    do msg.To.Insert("destination@mydomain.com")
    set msg.Subject= "File report"
    do ..Adapter.SendMail(msg)

    set pResponse = ##Class(Ens.StringResponse).%New("Ok")
    quit $$$OK
}

XData MessageMap
{
<MapItems>
  <MapItem MessageType="Ens.StringRequest">
    <Method>SendFtpReport</Method>
  </MapItem>

</MapItems>
}

}

I hope helps you.

Regards,
Francisco Lopez

Kurro Lopez · Sep 5, 2019 go to post

Last time, we have a value of 10 and the error increases more frequently, even when I was loading files.

So, the idea is to put a value like 30 seconds to allow that time the TCP disconnection. If I change the value to 30 (or 60), can the process open the TCP connection automatically and try to connect to FTP? If I leave it indefinitely (-1), is there a way to make the connection again?

Kurro Lopez · Jul 17, 2019 go to post

Hi Vikram,

Have you checked if you have granted privileges?

Best regards,

Francisco Lopez

Kurro Lopez · May 10, 2019 go to post

Well, next time I need to read the documentation in depth.

There is a base method to check if a class extends of other one

set obj = ##class(MyLibrary.ChildClass01).%New()

## this retrieves 1
w obj.%Extends("MyLibrary.ParentClass")

## this retrieves 0
w obj.%Extends("MyLibrary.ParentClassFake")

This has been a "Rubber duck", this is a sample of guide-book of rubber duck. wink

More info Clase %Library.SystemBase

Best regards,

Francisco López

Kurro Lopez · May 3, 2019 go to post

Hi,

Try the following code. It only works if the class parent is Ens.DataTransformDTL

// Create a query to get only my class (in MyClass and sub folders)

set query="SELECT ID FROM %Dictionary.ClassDefinition WHERE ID LIKE 'MyClass.%' AND super='Ens.DataTransformDTL'"

set tStatement = ##class(%SQL.Statement).%New() 

set qStatus=tStatement.%Prepare(query)

set tResult = tStatement.%Execute()

while tResult.%Next() {

   set dtlName = tResult.%Get("ID")

   set classObject = $CLASSMETHOD(dtlName ,"%New")
   
   write !,"DTL: "_dtlName
   write !,"Source type: "_classObject.GetSourceType()
   write !,"Target type: "_classObject.GetTargetType()
   write !

}

Remember: It works only if the class inherits from Ens.DataTransformDTL , if you know which class is the one that inherits the DTL you want to examine, change the name of the value of 'Super' in the previous query

Best regards,

Francisco Lopez

Kurro Lopez · Apr 30, 2019 go to post

Please, use the DTL class properties

set obj=##class(EXC.DTL.Lamont).%New()

write 'Source type: '_obj.GetSourceType()

write 'Target type: '_obj.GetTargetType()

Have a look the following documentation

Ens.DataTransformDTL

Best regards,

Francisco López

Kurro Lopez · Apr 18, 2019 go to post

Hi,

You need to map the other Global database into your namespace. This is the only way to have visibility of other database

Kurro Lopez · Aug 30, 2018 go to post

Dear all... problem solved.

I've created a new FTP server (based on IIS) and it works without problem.

The previous one was created with Filezilla server. 

Fortunately, the client has an FTP server based on IIS, so with this test we consider the integration in their preproduction environment will be fine.

Note: I've changed the "Server List Style" to "MSDOS" for this new server ;)

Thanks to all for your time.

Best regards,

Francisco López

Kurro Lopez · Jun 22, 2018 go to post

Hi,
Unfortunately, you should remove it manually. after, you should remove it in your local workspace, because if you want to synchronize your application, the package would be in your workspace again.

Best regards

Kurro Lopez · Jun 19, 2018 go to post

Hi Dani,

This class uses EnsLib.FTP.InboundAdapter, according to the documentation, this is the path on the Ensemble server to save a copy of each file received from the FTP server. That is not a FTP folder.

If you want to move the file processed into a FTP folder after processed, you should get the file from this folder and put it manually.

Have a look the link Using the FTP Inbound Adapter and Settings for the FTP Inbound Adapter

Have a nice day

Francisco López

Kurro Lopez · Jan 18, 2018 go to post

Hi Sam.

Why not create a TCP listener Service and link the message to your rule?

Using a tool to send HL7 message you can debug your rule. (https://sourceforge.net/projects/hl7inspector/)

I use to use HL7 Inspector to send message and I've debugged my code by this way.

There is not a direct way to test your code in Studio.

Best regards,

Francisco López

Kurro Lopez · Jan 10, 2018 go to post

If you really need a double key, use a persistence class instead.

You can define your fields and the key you want. You only need one instance of the object and find using the index.

The Looup table  was designed to be used as a dictionary, do not try to use an object for another purpose.

Best regards

Kurro Lopez · Sep 20, 2017 go to post

Hi Conor.

If you try to convert directly this datetime to a $HOROLOG format, you'll have problems :)

Date is a valid format, however the time needs to convert a valid format, so modify the variable to convert a valid datetime format.

set myTimeStamp="20160105125915"

set myTimeStampValid=$EXTRACT(fecha,1,4)_"-"_$EXTRACT(fecha,5,6)_"-"_$EXTRACT(fecha,7,8)_" "_$EXTRACT(fecha,9,10)_":"_$EXTRACT(fecha,11,12)_":"_$EXTRACT(fecha,13,14)

Then you have a datetime in format YYY-mm-dd HH:MM:ss

Now, you need to convert this variable to $HOROLOG format

set myTimeStampHorolog=$ZDATETIMEH(myTimeStampValid,3,1)

now, convert to UTC using your local time, if you know what is the UTC difference, apply directly.

Example: I'm in Spain, so is CET (UTC+1), however in summer (CEST) is UTC+2

If you use the method ##class(%SYSTEM.Util).LocalWithZTIMEZONEtoUTC you'll have the UTC as zone time, but your Ensemble doesn't know if it's Summer o Winter time.

if is Summer time, you need to reduce an hour your local time

set myTimeStampUTC=##class(%SYSTEM.Util).LocalWithZTIMEZONEtoUTC(myTimeStampHorolog)
;; IF SUMMER TIME, REDUCE ONE HOUR
set myTimeStampUTC=$ZDATETIMEH($SYSTEM.SQL.DATEADD("hour",-1,myTimeStampUTC),3,1)

if you want to compare both datetimes (now, I'm in CEST, so I'm in UTC+2)

write "My local time:"_$ZDATETIME(myTimeStampHorolog,3,1)
write "UTC time:"_$ZDATETIME(myTimeStampUTC,3,1)

The result is:

My local timestamp:2016-01-05 12:59:15

UTC timestamp:2016-01-05 10:59:15

Now, you have the same problem, you have a time separated by ":", so only need to revert the conversion

set myUTC=$ZDATE(myTimeStampUTC,8)_$REPLACE($ZTIME($PIECE(myTimeStampUTC,",",*),1),":","")

and compare:

write myTimeStamp

write myUTC

Check the info about theses methods:

$ZDATETIMEH

$ZDATETIME

$EXTRACT

##class(%SYSTEM.Util).LocalWithZTIMEZONEtoUTC

I hope I have solved your problem

Best regards,

Francisco Lopez

P.S. Don't forget check the answer if it's the correct answer.

P.P.S. [EDITED] According to Eduard Lebedyuk (see below), you can replace

set myTimeStampValid=$EXTRACT(fecha,1,4)_"-"_$EXTRACT(fecha,5,6)_"-"_$EXTRACT(fecha,7,8)_" "_$EXTRACT(fecha,9,10)_":"_$EXTRACT(fecha,11,12)_":"_$EXTRACT(fecha,13,14)

to

set myTimeStampValid=$SYSTEM.SQL.TOTIMESTAMP(myTimeStamp,"YYYYMMDDHHMISS")

Thanks Mr. Lebedyuk 

Kurro Lopez · Jun 14, 2017 go to post

Thanks to both,

I don't want to create a new account, cuz I can lose all my entries, and I couldn't link my account to Global Master one.

The account to WRC is other one, and I want to save it as it is.

Other option? wink

Kurro Lopez · Apr 26, 2017 go to post

Hi,

We are using Atelier with TFS and we haven't problems with it.

Sometimes, I have to check out the file manually because the synchronize process doesn't check out automatically. Some members of my team do it automatically but I don't. Don't know.

If you want to install TFS plugin, I've published a quick tutorial How to install and use TFS in Atelier. Please, have a look 

Best regards.

Kurro Lopez · Mar 6, 2017 go to post

It's easy,

As Eduard has exposed, you can pass a JSon as content of your Api

check that application/json is included into headers collection

Kurro Lopez · Mar 3, 2017 go to post

Solved...

I'm very sorry for this question, the answer was in my face and I didn't see it.

The plus sign is a special character in URL, so it should be replaced with "%2b" to escape the character.

I'm ashamed to think that this problem was too simple

I should call

http://localhost:57772/MyApp/login?login=flopez@salutic.es&password=7d%2brcUBPWF0wtMs4PHiluA==&app=MYAPP

Best regards,

Francisco