script listAndCountBlocks

Please use this forum to post feedback and suggestions related to QCAD.

Moderator: andrew

Post Reply
Jose Vieira
Newbie Member
Posts: 8
Joined: Sat May 16, 2015 10:12 pm

script listAndCountBlocks

Post by Jose Vieira » Sat Mar 08, 2025 2:05 am

Hello!
I'm using chatopenai to create some scripts for QCad, as I know nothing about js language, and the result is amazing.
Look that, it lists and count all blocks in a draw:

function listAndCountBlocks() {
var appWin = RMainWindow.getMainWindow();
if (!appWin) {
qDebug("Erro: não foi possível obter a janela principal.");
return;
}

var doc = EAction.getDocument();
var di = EAction.getDocumentInterface();

if (!doc || !di) {
qDebug("Erro: não foi possível obter o documento ou a interface do documento.");
return;
}

var ids = doc.queryAllEntities();
var blockCounts = {};

for (var i = 0; i < ids.length; i++) {
var entity = doc.queryEntity(ids);

// Verifica se a entidade é uma inserção de bloco
if (isBlockReferenceEntity(entity)) {
var blockName = entity.getReferencedBlockName();
if (blockName in blockCounts) {
blockCounts[blockName]++;
} else {
blockCounts[blockName] = 1;
}
}
}

// Criar mensagem com os blocos e suas quantidades
var message = "Lista de blocos inseridos no desenho:\n";
for (var block in blockCounts) {
message += "Bloco: " + block + " - Quantidade: " + blockCounts[block] + "\n";
}

// Exibir a mensagem
qDebug(message);
QMessageBox.information(appWin, "Blocos no Desenho", message);
}

// Chama a função para listar e quantificar todos os blocos inseridos
listAndCountBlocks();

CVH
Premier Member
Posts: 4944
Joined: Wed Sep 27, 2017 4:17 pm

Re: script listAndCountBlocks

Post by CVH » Sat Mar 08, 2025 5:57 am

Hi,

First remark: Please include code in a code panel.
Select the code in your topic and use the button [<>]
Please apply that by editing your post.

Looks neater and better structured because no leading space is removed.
Even long scripts are displayed nicely in a limited box.


:arrow: Amazing perhaps but AI is known to copy over wrong things found online with the same ease.

Code: Select all

if (!appWin) { ... }
if (!doc || !di) { ... }
Are such examples, the second line is probably a copy of code in this contribution by 'bowl'.
That was corrected in a reply.

It is functional but we should use the QCAD library function isNull(object). (See GitHub)
Every object in JavaScript is 'Truthy', except document.all, except those that are 'Falsy'
!doc is then true when doc = undefined otherwise NOT returns false.


There we make use of the EAction functions and library functions these resources should be included at the top.
Probably already included when the QCAD GUI is up ... But never take things for granted.

Code: Select all

    include("scripts/EAction.js");
    include("scripts/library.js");

Not really clever because it queries all entities from the document and then filters them one by one on RBlockReferenceEntity.
Then it queries a new clone of each RBlockReferenceEntity while nothing is going to be altered.

:arrow: But remark that this must fail because the queried ID is the list with IDs and NOT a single ID in that list by index = i.
Running your script with XC throws this exception:
  • Script exception in script 'C:/## obscured##/JoseVieiraScript.js': Error: : -1: -1: Wrong number/types of arguments for RDocument.queryEntity(). <native>(70,69) at -1 listAndCountBlocks() at 20 anonymous() at 46 <anonymous>() at :scripts/Misc/MiscDevelopment/RunScript/RunScript.js:120 <eval>() at 1 <native>() at -1 main() at :scripts\autostart.js:839 <global>() at :scripts\autostart.js:852
RDocument.queryEntity(<value=id>) can not query a whole array with entity IDs :!:
It is intended to query ONE entity by a unique ID.

The more correct code should be:

Code: Select all

    // Get list with IDs:
    var ids = doc.queryAllEntities(false, false, RS.EntityBlockRef);    // NOTundone, NOTallBlocks, filtered by type
    var blockCounts = {};

    // Process each ID in the list with BlockRefs IDs:
    for (var i = 0; i < ids.length; i++) {
        var id = ids[i];                           // One ID from the list of IDs by index i	       
        var entity = doc.queryEntityDirect(id);    // Nothing is going to be altered

Also remark that this is limited for the current displayed Block content.
When that is Model_Space it will not list Block References used in other Blocks ... 'Stacked Blocks'.

Regards,
CVH

Post Reply

Return to “QCAD Suggestions and Feedback”