<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Data tables in Discussions</title>
    <link>https://community.jmp.com/t5/Discussions/Data-tables/m-p/915297#M107561</link>
    <description>&lt;P&gt;Here is a fleshed out piece of JSL that takes Jarmo's JSL and expands on it to give you the results you show in your initial discussion.&lt;/P&gt;
&lt;P&gt;It uses Associative arrays to find the intersection of both the column names that appear in all 3 tables, and then also in the values that appear in the selected column.&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;It also uses the Update Platform to move the results back into the original 3 tables.&amp;nbsp; The methodology should be pretty efficient even on very large data tables.&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="txnelson_0-1764100356749.png" style="width: 664px;"&gt;&lt;img src="https://community.jmp.com/t5/image/serverpage/image-id/87710i160BB56B737D2575/image-dimensions/664x541?v=v2" width="664" height="541" role="button" title="txnelson_0-1764100356749.png" alt="txnelson_0-1764100356749.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&amp;nbsp;&lt;/PRE&gt;
&lt;PRE&gt;&lt;CODE class=" language-jsl"&gt;Names Default To Here( 1 );
dts = Get Data Table List();

If( N Items( dts ) &amp;lt; 2,
	Throw( "Not enough tables open" )
);

tables = dts &amp;lt;&amp;lt; get name;

// Create the table and column selection window
nw = New Window( "",
	H List Box(
		// Define the Table selection box
		Panel Box( "Select tables",
			lb_tables = List Box(
				tables,
				maxselected( 3 ),
				&amp;lt;&amp;lt;Set Function(
					Function( {this},
						// Get the tables selected by the user
						sel = this &amp;lt;&amp;lt; get selected;
						// If 3 tables have not been selected just return
						// otherwise, find all of the columns that are common
						// in all 3 tables.
						// Note: Only character columns are evaluated
						//       Column names must be named exactly the same way
						If( N Items( sel ) &amp;lt; 3,
							pickPBox &amp;lt;&amp;lt; visibility( "Collapse" );
							Return( 0 );
						,
							// Assign shortcut handles to the 3 data tables 
							dtOne = Data Table( (lb_tables &amp;lt;&amp;lt; get selected)[1] );
							dtTwo = Data Table( (lb_tables &amp;lt;&amp;lt; get selected)[2] );
							dtThree = Data Table( (lb_tables &amp;lt;&amp;lt; get selected)[3] ); 

							// Extract the character column names from each data table and
							// move them into an Associative Array
							accOne = Associative Array( dtOne &amp;lt;&amp;lt; get column names(character) );
							accTwo = Associative Array( dtTwo &amp;lt;&amp;lt; get column names(character)  );
							accThree = Associative Array( dtThree &amp;lt;&amp;lt; get column names(character)  );

							// Use the Intersect() funtion to find common column names
							accOne &amp;lt;&amp;lt; Intersect( accTwo );
							accOne &amp;lt;&amp;lt; Intersect( accThree );
							cols = accOne &amp;lt;&amp;lt; get keys;
					
							// If at least one column name is found, display the columns
							// for selection
							If( Length( cols ) &amp;gt; 0,
								lb_columns &amp;lt;&amp;lt; Set Items( cols );
								pickPBox &amp;lt;&amp;lt; visibility( "Visible" );
							);
						);
					)
				)
			), 

		),
		// Define the column selection box
		pickPBox = Panel Box( "Pick Column",
			lb_columns = List Box(
				{},
				Max Selected( 1 ),
				&amp;lt;&amp;lt;Set Function(
					Function( {this},
						sel = this &amp;lt;&amp;lt; get selected;
						// If a column has been selected, enable the OK button
						If( N Items( sel ) &amp;lt; 1,
							bbOK &amp;lt;&amp;lt; enable( 0 );
							Return( 0 );
						,
							bbOK &amp;lt;&amp;lt; enable( 1 )
						);
					)
				)
			)
		),
		// Define the Actions box
		Panel Box( "Actions",
			Lineup Box( N Col( 1 ), 
				xsel = sel[1];
				// Define the OK button and what to do when clicked
				bbOK = Button Box( "OK",
					// Copy the values from the selected column from each selected data table
					// into an Associative Array....Note: code is using the previously used arrays,
					// but recreating them with the new data
					accOne = Associative Array( Column( dtOne, xsel ) &amp;lt;&amp;lt; get values );
					accTwo = Associative Array( Column( dtTwo, xsel ) &amp;lt;&amp;lt; get values );
					accThree = Associative Array( Column( dtThree, xsel ) &amp;lt;&amp;lt; get values );

					// Use the Intersect() function to find all values found 
					// in the selected column in all 3 data tables
					accOne &amp;lt;&amp;lt; Intersect( accTwo );
					accOne &amp;lt;&amp;lt; Intersect( accThree );
					theArray = accOne &amp;lt;&amp;lt; get keys;

					// The method that is used to add the new column with Present in All column
					// uses the Update Platform where 2 tables are joined with matching rows
					// being added to the table being updated.  To do that, a temporary table
					// is created containing the common data values found in the previous step.
					
					// Add a Transitional table
					dtMatch = New Table( "Match",
						add rows( Length( theArray ) ),
						New Column( xsel, character ),
						New Column( "PresentinAll", set each value( 1 ) )
					);
					// Add the common data values to the matching column
					Column( dtMatch, xsel ) &amp;lt;&amp;lt; set values( theArray );

					// For each of the 3 target tables, update them with the 
					// data from the Match data table
					dtOne &amp;lt;&amp;lt; Update(
						With( dtMatch ),
						Match Columns( Column( dtOne, xsel ) = Column( dtMatch, xsel ) )
					);
					// The Updating added a 1 for all rows that have common column values,
					// and the statement below, add a 0 to all of the other rows in the column
					Try(
						dtOne:PresentinAll[dtOne &amp;lt;&amp;lt; get rows where( Is Missing( dtOne:PresentinAll ) == 1 )]
						 = 0
					);
					dtTwo &amp;lt;&amp;lt; Update(
						With( dtMatch ),
						Match Columns( Column( dtTwo, xsel ) = Column( dtMatch, xsel ) )
					);
					Try(
						dtTwo:PresentinAll[dtTwo &amp;lt;&amp;lt; get rows where( Is Missing( dtTwo:PresentinAll ) == 1 )]
						 = 0
					);
					dtThree &amp;lt;&amp;lt; Update(
						With( dtMatch ),
						Match Columns( Column( dtThree, xsel ) = Column( dtMatch, xsel ) )
					);
					Try(
						dtThree:PresentinAll[dtThree &amp;lt;&amp;lt; get rows where(
							Is Missing( dtThree:PresentinAll ) == 1
						)] = 0
					);
					nw &amp;lt;&amp;lt; close window;
					// Delete the temporary transistional data table.
					Close( dtMatch, nosave );
				),
				Button Box( "Cancel", nw &amp;lt;&amp;lt; close window )
			)
		)
	)
);
// Set the initial values for the Column selection box and the OK button
pickPBox &amp;lt;&amp;lt; visibility( "Collapse" );
bbOK &amp;lt;&amp;lt; enable( 0 );
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Wed, 26 Nov 2025 17:35:07 GMT</pubDate>
    <dc:creator>txnelson</dc:creator>
    <dc:date>2025-11-26T17:35:07Z</dc:date>
    <item>
      <title>Data tables</title>
      <link>https://community.jmp.com/t5/Discussions/Data-tables/m-p/915139#M107545</link>
      <description>&lt;P&gt;Hi,&amp;nbsp;&lt;BR /&gt;&lt;BR /&gt;I want to compare more than 2 tables in JMP for a common column present in all the tables. Now i want to return a 1 if the values in that specific column exists in each table otherwise 0. This im able to do for some predefined tables and by using a JSL script which adds an extra column in each table and return 0 or 1.&amp;nbsp;&lt;BR /&gt;But i want to make this script generic so that i dont need to predefine the name of tables. It should be like, whenever i run this script, it should ask me which tables i want to compare.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;After that, i also want this script to work in such a way it can also give me the option to select which column i want to compare&lt;/P&gt;
&lt;P&gt;Currently, Im using this script&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-jsl"&gt;// Get references to the three tables
dt1 = Data Table("Untitled 9");
dt2 = Data Table("Untitled 10");
dt3 = Data Table("Untitled 11");

// Extract ID values from each table
ids1 = dt1:ID &amp;lt;&amp;lt; Get Values;
ids2 = dt2:ID &amp;lt;&amp;lt; Get Values;
ids3 = dt3:ID &amp;lt;&amp;lt; Get Values;

// Find common IDs manually
commonIDs = {};
For(i = 1, i &amp;lt;= N Items(ids1), i++,
	If(Contains(ids2, ids1[i]) &amp;amp; Contains(ids3, ids1[i]),
		Insert Into(commonIDs, ids1[i])
	)
);

// Function to add indicator column
AddIndicatorColumn = Function({dt},
	dt &amp;lt;&amp;lt; New Column("PresentInAll",
		Numeric,
		Formula(If(Contains(commonIDs, :ID), 1, 0))
	)
);

// Apply to all tables
AddIndicatorColumn(dt1);
AddIndicatorColumn(dt2);
AddIndicatorColumn(dt3);&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Edit (jthi): added jsl formatting&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;Selecting three tables Untitled 9, Untitled 10 and Untitled 11 and the column im comparing is "ID"&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Please help on this,&lt;/P&gt;
&lt;P&gt;Thanks&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Denver69_0-1764053353795.png" style="width: 400px;"&gt;&lt;img src="https://community.jmp.com/t5/image/serverpage/image-id/87660iEBB94A904E554118/image-size/medium?v=v2&amp;amp;px=400" role="button" title="Denver69_0-1764053353795.png" alt="Denver69_0-1764053353795.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 25 Nov 2025 06:55:46 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/Data-tables/m-p/915139#M107545</guid>
      <dc:creator>Denver69</dc:creator>
      <dc:date>2025-11-25T06:55:46Z</dc:date>
    </item>
    <item>
      <title>Re: Data tables</title>
      <link>https://community.jmp.com/t5/Discussions/Data-tables/m-p/915150#M107546</link>
      <description>&lt;P&gt;How many rows your tables have and many unique values? This can affect how this should be done to avoid performance issues.&lt;/P&gt;</description>
      <pubDate>Tue, 25 Nov 2025 06:58:12 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/Data-tables/m-p/915150#M107546</guid>
      <dc:creator>jthi</dc:creator>
      <dc:date>2025-11-25T06:58:12Z</dc:date>
    </item>
    <item>
      <title>Re: Data tables</title>
      <link>https://community.jmp.com/t5/Discussions/Data-tables/m-p/915154#M107548</link>
      <description>&lt;P&gt;Anyway, you can build the UI using Get Data Table List + List Boxes. Below is quick version which can help with getting started&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-jsl"&gt;Names Default To Here(1);
dts = Get Data Table List();

If(N Items(dts) &amp;lt; 2,
	Throw("Not enough tables open");
);

run_expr = Expr(
	Show(lb_tables &amp;lt;&amp;lt; get selected, lb_columns &amp;lt;&amp;lt; get selected);
);

tables = dts &amp;lt;&amp;lt; get name;

nw = New Window("",
	H List Box(
		Panel Box("Select tables", 
			lb_tables = List Box(tables, 
				&amp;lt;&amp;lt; Set Function(Function({this},
					sel = this &amp;lt;&amp;lt; get selected;
					If(N Items(sel) &amp;lt; 1,
						return(0);
					);
					cols = Datatable(sel[1]) &amp;lt;&amp;lt; Get Column Names("String");
					lb_columns &amp;lt;&amp;lt; Set Items(cols);
				))
			),
		),
		Panel Box("Pick Column",
			lb_columns = List Box({}, &amp;lt;&amp;lt; Set Max Selected(1))
		),
		Panel Box("Actions",
			Lineup Box(N Col(1),
				Button Box("OK",
					run_expr
				),
				Button Box("Cancel",
					nw &amp;lt;&amp;lt; close window;
				)
			)
		)
	)
);

Write();
&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Tue, 25 Nov 2025 07:54:30 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/Data-tables/m-p/915154#M107548</guid>
      <dc:creator>jthi</dc:creator>
      <dc:date>2025-11-25T07:54:30Z</dc:date>
    </item>
    <item>
      <title>Re: Data tables</title>
      <link>https://community.jmp.com/t5/Discussions/Data-tables/m-p/915297#M107561</link>
      <description>&lt;P&gt;Here is a fleshed out piece of JSL that takes Jarmo's JSL and expands on it to give you the results you show in your initial discussion.&lt;/P&gt;
&lt;P&gt;It uses Associative arrays to find the intersection of both the column names that appear in all 3 tables, and then also in the values that appear in the selected column.&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;It also uses the Update Platform to move the results back into the original 3 tables.&amp;nbsp; The methodology should be pretty efficient even on very large data tables.&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="txnelson_0-1764100356749.png" style="width: 664px;"&gt;&lt;img src="https://community.jmp.com/t5/image/serverpage/image-id/87710i160BB56B737D2575/image-dimensions/664x541?v=v2" width="664" height="541" role="button" title="txnelson_0-1764100356749.png" alt="txnelson_0-1764100356749.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&amp;nbsp;&lt;/PRE&gt;
&lt;PRE&gt;&lt;CODE class=" language-jsl"&gt;Names Default To Here( 1 );
dts = Get Data Table List();

If( N Items( dts ) &amp;lt; 2,
	Throw( "Not enough tables open" )
);

tables = dts &amp;lt;&amp;lt; get name;

// Create the table and column selection window
nw = New Window( "",
	H List Box(
		// Define the Table selection box
		Panel Box( "Select tables",
			lb_tables = List Box(
				tables,
				maxselected( 3 ),
				&amp;lt;&amp;lt;Set Function(
					Function( {this},
						// Get the tables selected by the user
						sel = this &amp;lt;&amp;lt; get selected;
						// If 3 tables have not been selected just return
						// otherwise, find all of the columns that are common
						// in all 3 tables.
						// Note: Only character columns are evaluated
						//       Column names must be named exactly the same way
						If( N Items( sel ) &amp;lt; 3,
							pickPBox &amp;lt;&amp;lt; visibility( "Collapse" );
							Return( 0 );
						,
							// Assign shortcut handles to the 3 data tables 
							dtOne = Data Table( (lb_tables &amp;lt;&amp;lt; get selected)[1] );
							dtTwo = Data Table( (lb_tables &amp;lt;&amp;lt; get selected)[2] );
							dtThree = Data Table( (lb_tables &amp;lt;&amp;lt; get selected)[3] ); 

							// Extract the character column names from each data table and
							// move them into an Associative Array
							accOne = Associative Array( dtOne &amp;lt;&amp;lt; get column names(character) );
							accTwo = Associative Array( dtTwo &amp;lt;&amp;lt; get column names(character)  );
							accThree = Associative Array( dtThree &amp;lt;&amp;lt; get column names(character)  );

							// Use the Intersect() funtion to find common column names
							accOne &amp;lt;&amp;lt; Intersect( accTwo );
							accOne &amp;lt;&amp;lt; Intersect( accThree );
							cols = accOne &amp;lt;&amp;lt; get keys;
					
							// If at least one column name is found, display the columns
							// for selection
							If( Length( cols ) &amp;gt; 0,
								lb_columns &amp;lt;&amp;lt; Set Items( cols );
								pickPBox &amp;lt;&amp;lt; visibility( "Visible" );
							);
						);
					)
				)
			), 

		),
		// Define the column selection box
		pickPBox = Panel Box( "Pick Column",
			lb_columns = List Box(
				{},
				Max Selected( 1 ),
				&amp;lt;&amp;lt;Set Function(
					Function( {this},
						sel = this &amp;lt;&amp;lt; get selected;
						// If a column has been selected, enable the OK button
						If( N Items( sel ) &amp;lt; 1,
							bbOK &amp;lt;&amp;lt; enable( 0 );
							Return( 0 );
						,
							bbOK &amp;lt;&amp;lt; enable( 1 )
						);
					)
				)
			)
		),
		// Define the Actions box
		Panel Box( "Actions",
			Lineup Box( N Col( 1 ), 
				xsel = sel[1];
				// Define the OK button and what to do when clicked
				bbOK = Button Box( "OK",
					// Copy the values from the selected column from each selected data table
					// into an Associative Array....Note: code is using the previously used arrays,
					// but recreating them with the new data
					accOne = Associative Array( Column( dtOne, xsel ) &amp;lt;&amp;lt; get values );
					accTwo = Associative Array( Column( dtTwo, xsel ) &amp;lt;&amp;lt; get values );
					accThree = Associative Array( Column( dtThree, xsel ) &amp;lt;&amp;lt; get values );

					// Use the Intersect() function to find all values found 
					// in the selected column in all 3 data tables
					accOne &amp;lt;&amp;lt; Intersect( accTwo );
					accOne &amp;lt;&amp;lt; Intersect( accThree );
					theArray = accOne &amp;lt;&amp;lt; get keys;

					// The method that is used to add the new column with Present in All column
					// uses the Update Platform where 2 tables are joined with matching rows
					// being added to the table being updated.  To do that, a temporary table
					// is created containing the common data values found in the previous step.
					
					// Add a Transitional table
					dtMatch = New Table( "Match",
						add rows( Length( theArray ) ),
						New Column( xsel, character ),
						New Column( "PresentinAll", set each value( 1 ) )
					);
					// Add the common data values to the matching column
					Column( dtMatch, xsel ) &amp;lt;&amp;lt; set values( theArray );

					// For each of the 3 target tables, update them with the 
					// data from the Match data table
					dtOne &amp;lt;&amp;lt; Update(
						With( dtMatch ),
						Match Columns( Column( dtOne, xsel ) = Column( dtMatch, xsel ) )
					);
					// The Updating added a 1 for all rows that have common column values,
					// and the statement below, add a 0 to all of the other rows in the column
					Try(
						dtOne:PresentinAll[dtOne &amp;lt;&amp;lt; get rows where( Is Missing( dtOne:PresentinAll ) == 1 )]
						 = 0
					);
					dtTwo &amp;lt;&amp;lt; Update(
						With( dtMatch ),
						Match Columns( Column( dtTwo, xsel ) = Column( dtMatch, xsel ) )
					);
					Try(
						dtTwo:PresentinAll[dtTwo &amp;lt;&amp;lt; get rows where( Is Missing( dtTwo:PresentinAll ) == 1 )]
						 = 0
					);
					dtThree &amp;lt;&amp;lt; Update(
						With( dtMatch ),
						Match Columns( Column( dtThree, xsel ) = Column( dtMatch, xsel ) )
					);
					Try(
						dtThree:PresentinAll[dtThree &amp;lt;&amp;lt; get rows where(
							Is Missing( dtThree:PresentinAll ) == 1
						)] = 0
					);
					nw &amp;lt;&amp;lt; close window;
					// Delete the temporary transistional data table.
					Close( dtMatch, nosave );
				),
				Button Box( "Cancel", nw &amp;lt;&amp;lt; close window )
			)
		)
	)
);
// Set the initial values for the Column selection box and the OK button
pickPBox &amp;lt;&amp;lt; visibility( "Collapse" );
bbOK &amp;lt;&amp;lt; enable( 0 );
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 26 Nov 2025 17:35:07 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/Data-tables/m-p/915297#M107561</guid>
      <dc:creator>txnelson</dc:creator>
      <dc:date>2025-11-26T17:35:07Z</dc:date>
    </item>
  </channel>
</rss>

