My comments aren’t in any particular order.
Aren’t you closing the database in the wrong loop? It looks to me like you are closing it after examining the first procedure in the database, which isn’t going to work too well when you try to look at the second procedure in the database.
Also, you might want to check to see if a database is already open, and if so, leave it open.
I would also recommend allowing the user to cancel the choosefolderdialog and gettext dialogs.
Minor niggle – checking for
bkFileName notcontains "/PanoramaX.app/Contents/Resources/"
isn’t going to hurt anything, but it will never be true since choosefiledialog won’t select a folder inside a bundle. I made that suggestion for checking whether an open database was part of Panorama, but in this case you’re not going off the list of open files.
Since you want to generate a report that shows the line number of multiple occurrences of the search text, the views( function isn’t going to work for you. So you’re fine with the getproceduretext statement. I like your idea of generating a report, but instead of copying it into the clipboard, I would suggest using the displaydata statement.
I wonder if it would be easier to start by adding line numbers to every line in the code, then do an arrayfilter to search for the text. Then you wouldn’t have a problem with duplicate lines as you do now, and I think the logic would be a bit simpler also. In fact I think you could do it all in one go.
arrayfilter bkProcText,bkProcLines,cr(),?(import() contains bkSearchString," Line "+seq()+": "+strip(import()),"")
Then you can skip most of your following logic, bkProcText is ready to put into the report. I haven’t tested it but it should be close.