Maybe you can make it so that you can use the shortcode like [list-products categories=”1,2,3″], and then explode them as an array to insert them as your terms?
<?php
function list_products_func($atts) {
$a = shortcode_atts(array(
'categories' => '',
), $atts);
// Check for multiple categories by comma
if ( strpos( $a['categories'], ',' ) !== false ) {
$terms = explode( $a['categories'] );
} else {
$terms = $a['categories'];
}
$args = array(
'posts_per_page' => -1,
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $terms // Your exploded terms array
)
),
'post_type' => 'product',
'orderby' => 'title,'
);
$products = new WP_Query($args);
echo "<table>";
while ($products->have_posts()) {
$products->the_post();
$product = new WC_Product(get_the_ID()); ?>
<tr class="product-list-item">
<td><a href="https://wordpress.stackexchange.com/questions/252258/<?php the_permalink(); ?>"><?php the_title(); ?></a></td>
<td><?php echo get_the_excerpt(); ?></td>
<td><?php echo $product->get_price_html(); ?></td>
<td>
<?php echo woocommerce_quantity_input(
array(
'min_value' => 1,
'max_value' => $product->backorders_allowed() ? '' : $product->get_stock_quantity(),
)); ?>
</td>
<td><?php echo woocommerce_template_loop_add_to_cart(); ?></td>
</tr>
<?php
}
echo "</table>";
}
add_shortcode('list_products', 'list_products_func');
?>