Closed C00P5 closed 4 years ago
Hey, that would indeed be a great feature and the reason I did not yet implement it is because we are using the official powerquery-parser. What we receive from this library is the AST of your query and we traverse the AST and format the code accordingly. Unfortunately the comments are not part of the Ast. They are available however, but I will have to match the comments to the node that the comment belongs to by myself. Unfortunately this is not a trivial task and I didn't have time yet to implement it. I will update you as soon as I have time to implement this. Thanks for your suggestion.
Ok so I had some spare time yesterday in the evening and I looked into this. I found a very basic way of supporting comments: Line comments (with "//") will be always one whitespace after the last node and inline comments ("/ /") will be always seperated with one whitespace from the node to the left and to the right. It would be nice to be able to align all line comments e.g. to the same column. Unfortunately that would require some more work so maybe I will implement this in the future.
You can also now toggle includeComments in the options section in the formatter to configure whether comments should be included.
Please let me know if this is already sufficient for you or if any problems occur.
Well done and thanks. I tried a couple and it seems to keep the comments in the formatted PQ.
Even if a line space is inserted before the comment (even two line spaces) the comment runs on at the end of the previous line. I could live with that. Thanks again.
You're welcome.
I see, I didn't think about lines that only contain comments. I just uploaded a patch which seems to be working.
I put in this query:
let
MyFunc = (netValue as number /*test*/) =>
let /* asd */
//tests
MwSt = 0.19, //tests
/* testing */
valueAfterTax /* asd */ = netValue * (1 + MwSt) //test
in //tst
//iss
/*asd*/
//asd
//asd
valueAfterTax
in
//test
MyFunc
//test
I get out this
let
MyFunc = (netValue as number /*test*/ ) =>
let /* asd */
//tests
MwSt = 0.19, //tests
/* testing */
valueAfterTax /* asd */ = netValue * (1 + MwSt) //test
in //tst
//iss
/*asd*/
//asd
//asd
valueAfterTax
in
//test
MyFunc
//test
So I remove all empty lines but preserve newlines after comments. I also indent the comment to the next most node.
I also count inline comments to the line character count, so if you have a line
valueAfterTax /* aaaaaaaaa*/ = netValue * (1 + MwSt) //test
and you add many more as to the comment so that it will exceed the line length it will force the expression to break. On the other hand line comments do not affect the break behavior at the moment.
I'm not sure if I thought of all the edge-cases but all it seems to be working with all test-cases that I have right now. If you encounter any issues let me know.
It worked brilliantly. Thanks from DownUnder
let // Import AU ArTrnDetails db AUSource = Sql.Database("sqlserver.xxxxxx.local", "EncoreCompanyR"), AUdbo_ArTrnDetail = AUSource{[Schema = "dbo", Item = "ArTrnDetail"]}[Data], AUChangeDateTimeToDate = Table.TransformColumnTypes(AUdbo_ArTrnDetail, { {"InvoiceDate", type date} }), AUFilterDatesPerParameter = Table.SelectRows(AUChangeDateTimeToDate, each [InvoiceDate] >= StartTableDates), AURemovedOtherColumns = Table.SelectColumns(AUFilterDatesPerParameter, { "TrnYear", "TrnMonth", "Invoice", "InvoiceDate", "Branch", "Salesperson", "Customer", "StockCode", "Area", "ProductClass", "Warehouse", "CustomerClass", "QtyInvoiced", "NetSalesValue", "CostValue", "GlYear", "GlPeriod", "PostCurrency", "PostConvRate" }), AURemoveICSales = Table.SelectRows( AURemovedOtherColumns, each not Text.StartsWith([Branch], "9") ), AUCleanStkCodes = Table.SelectRows( AURemoveICSales, each not Text.Contains([StockCode], "Pric") and [StockCode] <> " " ), // Import EU ArTrnDetails db EUSource = Sql.Database("sqlserver.xxxxxx.local", "SysproCompanyE"), EUdbo_ArTrnDetail = EUSource{[Schema = "dbo", Item = "ArTrnDetail"]}[Data], EUChangeDateTimeToDate = Table.TransformColumnTypes(EUdbo_ArTrnDetail, { {"InvoiceDate", type date} }), EUFilterDatesPerParameter = Table.SelectRows(EUChangeDateTimeToDate, each [InvoiceDate] >= StartTableDates), EURemovedOtherColumns = Table.SelectColumns(EUFilterDatesPerParameter, { "TrnYear", "TrnMonth", "Invoice", "InvoiceDate", "Branch", "Salesperson", "Customer", "StockCode", "Area", "ProductClass", "Warehouse", "CustomerClass", "QtyInvoiced", "NetSalesValue", "CostValue", "GlYear", "GlPeriod", "PostCurrency", "PostConvRate" }), EURemoveICSales = Table.SelectRows( EURemovedOtherColumns, each not Text.StartsWith([Branch], "9") ), EUCleanStkCodes = Table.SelectRows( EURemoveICSales, each not Text.Contains([StockCode], "Pric") and [StockCode] <> " " ), // Import US ArTrnDetails db USSource = Sql.Database("sqlserver.xxxxxx.local", "SysproCompanyU"), USdbo_ArTrnDetail = USSource{[Schema = "dbo", Item = "ArTrnDetail"]}[Data], USChangeDateTimeToDate = Table.TransformColumnTypes(USdbo_ArTrnDetail, { {"InvoiceDate", type date} }), USFilterDatesPerParameter = Table.SelectRows(USChangeDateTimeToDate, each [InvoiceDate] >= StartTableDates), USRemovedOtherColumns = Table.SelectColumns(USFilterDatesPerParameter, { "TrnYear", "TrnMonth", "Invoice", "InvoiceDate", "Branch", "Salesperson", "Customer", "StockCode", "Area", "ProductClass", "Warehouse", "CustomerClass", "QtyInvoiced", "NetSalesValue", "CostValue", "GlYear", "GlPeriod", "PostCurrency", "PostConvRate" }), USRemoveICSales = Table.SelectRows( USRemovedOtherColumns, each not Text.StartsWith([Branch], "9") ), USCleanStkCodes = Table.SelectRows( USRemoveICSales, each not Text.Contains([StockCode], "Pric") and [StockCode] <> " " ), // Import SI ArTrnDetails db SISource = Sql.Database("sqlserver.xxxxxx.local", "SysproCompanyS"), SIdbo_ArTrnDetail = SISource{[Schema = "dbo", Item = "ArTrnDetail"]}[Data], SIChangeDateTimeToDate = Table.TransformColumnTypes(SIdbo_ArTrnDetail, { {"InvoiceDate", type date} }), SIFilterDatesPerParameter = Table.SelectRows(SIChangeDateTimeToDate, each [InvoiceDate] >= StartTableDates), SIRemovedOtherColumns = Table.SelectColumns(SIFilterDatesPerParameter, { "TrnYear", "TrnMonth", "Invoice", "InvoiceDate", "Branch", "Salesperson", "Customer", "StockCode", "Area", "ProductClass", "Warehouse", "CustomerClass", "QtyInvoiced", "NetSalesValue", "CostValue", "GlYear", "GlPeriod", "PostCurrency", "PostConvRate" }), SIRemoveICSales = Table.SelectRows( SIRemovedOtherColumns, each not Text.StartsWith([Branch], "9") ), SICleanStkCodes = Table.SelectRows( SIRemoveICSales, each not Text.Contains([StockCode], "Pric") and [StockCode] <> " " ), // Combine above queries CombineAll = Table.Combine({AUCleanStkCodes, EUCleanStkCodes, USCleanStkCodes, SICleanStkCodes}), //Merge Salesperson data LinkSalePersonNameTable = Table.NestedJoin( CombineAll, {"Branch", "Salesperson"}, SalSalesperson, {"Branch", "Salesperson"}, "SalSalesperson", JoinKind.LeftOuter ), ShowSalesPersonName = Table.ExpandTableColumn( LinkSalePersonNameTable, "SalSalesperson", {"Name"}, {"SalespersonName"} ), RemoveSalepersonCode = Table.RemoveColumns(ShowSalesPersonName, {"Salesperson"}), // Merge Foreign Exchange data TempChgGlYearToText = Table.TransformColumnTypes(RemoveSalepersonCode, {{"GlYear", type text}}), MergeAUDFx = Table.NestedJoin( TempChgGlYearToText, {"Branch", "GlYear"}, CurrencyAUDBase, {"CompanyCode", "SYSPROYear"}, "CurrencyAUDBase", JoinKind.LeftOuter ), SelectCurrencyAUDBase = Table.ExpandTableColumn(MergeAUDFx, "CurrencyAUDBase", {"AUDFx"}, { "AUDFx" }), MergeEURFx = Table.NestedJoin( SelectCurrencyAUDBase, {"Branch", "GlYear"}, CurrencyEURBase, {"CompanyCode", "SYSPROYear"}, "CurrencyEURBase", JoinKind.LeftOuter ), SelectCurrencyEURBase = Table.ExpandTableColumn(MergeEURFx, "CurrencyEURBase", {"EURFx"}, { "EURFx" }), MergeUSDFx = Table.NestedJoin( SelectCurrencyEURBase, {"Branch", "GlYear"}, CurrencyUSDBase, {"CompanyCode", "SYSPROYear"}, "CurrencyUSDBase", JoinKind.LeftOuter ), SelectCurrencyUSDBase = Table.ExpandTableColumn(MergeUSDFx, "CurrencyUSDBase", {"USDFx"}, { "USDFx" }), // Create FEx values from Base Ccy values CreateNetSaleAUD = Table.AddColumn(SelectCurrencyUSDBase, "NetSaleAUD", each Number.Round( [NetSalesValue] / [AUDFx], 2 )), CreateNetSaleEUR = Table.AddColumn(CreateNetSaleAUD, "NetSaleEUR", each Number.Round( [NetSalesValue] / [EURFx], 2 )), CreateNetSaleUSD = Table.AddColumn(CreateNetSaleEUR, "NetSaleUSD", each Number.Round( [NetSalesValue] / [USDFx], 2 )), CreateNetCostAUD = Table.AddColumn(CreateNetSaleUSD, "NetCostAUD", each Number.Round( [CostValue] / [AUDFx], 2 )), CreateNetCostEUR = Table.AddColumn(CreateNetCostAUD, "NetCostEUR", each Number.Round( [CostValue] / [EURFx], 2 )), CreateNetCostUSD = Table.AddColumn(CreateNetCostEUR, "NetCostUSD", each Number.Round( [CostValue] / [USDFx], 2 )), ChangedType = Table.TransformColumnTypes(CreateNetCostUSD, { {"NetSaleAUD", type number}, {"NetSaleEUR", type number}, {"NetSaleUSD", type number}, {"NetCostAUD", type number}, {"NetCostEUR", type number}, {"NetCostUSD", type number}, {"GlYear", type number} }), // Clean tables of redundant Columns FinalSalesDetails = Table.RemoveColumns(ChangedType, { "PostCurrency", "PostConvRate", "AUDFx", "EURFx", "USDFx" }) in FinalSalesDetails
Cool, you're welcome. Greetings from Germany.
Not really a bug but an enhancement. If the source code has already been edited with comments "//" or "/ /", it would be nice to have these remain after parsing the editor.