Ultragrid Export Sort Order / Indicator - infragistics

To make a long story short, we have a legacy application which displays an infragistics grid where users can export the grid display. The issue I'm having is that there's a particular order in which they want the export to occur, and if I set the order within the grid view prior to export, it retains this order, however if I try to force it "on export", it doesn't seem to work despite trying to set it. Here's my code (VB), as you can see just prior to import I try to set the "sortindicator", but I suspect I'm missing something.
Dim FileName As String
Dim I As Integer
I = 1
FileName = "C:\ReconciliationReport.xls"
While System.IO.File.Exists(FileName)
FileName = "C:\ReconciliationReport_" & I & ".xls"
I = I + 1
End While
grdReconciliationReport.DisplayLayout.Bands(0).Columns("ReconciliationOrder").SortIndicator = Infragistics.Win.UltraWinGrid.SortIndicator.Ascending
UltraGridExcelExporter.Export(grdReconciliationReport, FileName)

During the export of the grid UltraGridExcelExporter creates its own copy of the Layout. This is done exactly to allow you to sort, hide, delete and any other action in the layout without changing the actual grid. To sort the grid by any column you need to handle ExportStarted event. The event argument contains reference to the clonned layout. You can use code like this:
Private Sub UltraGridExcelExporter_ExportStarted(sender As Object, e As ExcelExport.ExportStartedEventArgs) Handles UltraGridExcelExporter1.ExportStarted
Dim sortedCol As UltraGridColumn = e.Layout.Bands(0).Columns(1)
e.Layout.Bands(0).SortedColumns.Add(sortedCol, False, False)
End Sub

Related

Add empty option to List Validator

I'm trying to add the option to my users that, on a List Validator, to allow select any of the options or a blank option. Spreadjs has the IgnoreBlanks setting, which I use, so when the user uses the delete key or the backspace and deletes the cell it validates correctly.
However, I would love to use the same functionality as in Excel, which allows blank options in the list validator, in part of the list.
I've tried to target the <select> element that holds the list and programmatically add the empty element, however, it crashes after the user selects the empty option.
I've also tried to add different escaped characters to the list. If I select a character that represents an empty string or a tab, it won't add a new option to the list. If I use any strange character, or even the null character \0 you get a new option to select, but the content is that typical rectangle you see when your font doesn't have the character you're trying to display.
I've also tested using a regular ListValidator like in the example pages, not our custom functionality and doesn't work either.
https://www.grapecity.com/demos/spread/JS/TutorialSample/#/demos/basicDataValidator
I have also tried creating a FormulaListValidator, and if my range has empty cells I could then get an empty option on my list, however, because the range may have duplicates, I get duplicated options.
After researching a little bit I found a workaround in a different language which I adapted to Typescript (Angular 6)
export const getListValidatorFromArray = (spread: GC.Spread.Sheets.Workbook, data: any[]) => {
// saving validation list values in a hidden sheet
spread.addSheet(spread.getSheetCount());
const sheet = spread.getSheet(spread.getSheetCount() - 1);
sheet.visible(false);
for (let i = 0; i < data.length; i++) {
sheet.setValue(i, 0, data[i]);
}
// create validator based on the values
const dv = GC.Spread.Sheets.DataValidation.createFormulaListValidator(
'=' + sheet.name() + '!$A$1:' + sheet.name() + '!$A$' + data.length
);
return dv;
};
Note: This creates an extra sheet for each validator you create. Makes sure you reuse them as much as possible (i.e. assigning it to a variable when it's created, and reusing the variable for other columns/rows that use the same one).

This cell duplicates image in that cell in spreadsheet?

Very simple. Cell A1 has an image in it, which I supply through Insert:Picture:From File...
Now I want Cell A3 to automatically show the same picture. I simply can't find a way-- certainly the "=" doesn't work. At this point, I don't care if the images are "links" or embedded, I just want it to work. Can it? Thx.
Edit, 09-01-17, based on Jim K's idea, here's macro code I have installed:
REM ***** BASIC *****
Private oListener as Object
Private cellA1 as Object
Sub AddListener
Dim Doc, Sheet, Cell as Object
Doc = ThisComponent
Sheet = Doc.Sheets.getByName("Sheet1")
cellA1 = Sheet.getCellrangeByName("A1")
'create a listener
oListener = createUnoListener("Modify_","com.sun.star.util.XModifyListener")
'register the listener
cellA1.addModifyListener(oListener)
End Sub
Sub Modify_disposing(oEv)
End Sub
Sub RmvListener
cellA1.removeModifyListener(oListener)
End Sub
' macro jumps here when oListener detects modification of Sheet
Sub Modify_modified(oEv)
Doc = ThisComponent
Sheet = Doc.Sheets.getByIndex(0)
originCell = Sheet.getCellByPosition(0,0)
originValue = originCell.Value
if originValue then
print "originValue is " & originValue
else
print "originValue zero"
end if
End Sub
The problem, ironically, is that it works. It works for integers and {non-value}, I mean an empty cell.
So any integer not zero prints TRUE, zero prints FALSE, and empty cell prints FALSE.
But that's where it quits working-- any kind of string "asdf" also returns FALSE.
Maybe that could be fixed, but there's something a lot worse: When I paste an image in the cell, or use the Insert/Image/From File... menu, or Cut an existing image... Nothing happens! The Sheet Modified business does not trigger the expected routine.
Any hope? Thx.
As you discovered, the solution in my comment does not work, because the Content changed event will not trigger when images are added. I looked into other events as well, but they did not work either.
So instead, we can set up a function that runs periodically. Each time it runs, it checks the count of images, and if any have been added or removed, it calls update_copied_images() below, which currently simply reports the value of cell A1, as in your code.
As explained here, I have not gotten a timer loop to work in Basic without crashing, so we can use Python instead (a better language, so this is not a drawback in my opinion).
import time
from threading import Thread
import uno
COLUMN_A, COLUMN_B, COLUMN_C = 0, 1, 2
FIRST_ROW = 0
def start_counting_images(action_event=None):
t = Thread(target = keep_counting_images)
t.start()
def keep_counting_images():
oDoc = XSCRIPTCONTEXT.getDocument()
oSheet = oDoc.getSheets().getByIndex(0)
oDrawPage = oSheet.getDrawPage()
messageCell = oSheet.getCellByPosition(COLUMN_C, FIRST_ROW)
messageCell.setString("Starting...")
prevCount = -1
while hasattr(oDoc, 'calculateAll'): # keep going until document is closed
count = oDrawPage.Count
if prevCount == -1 or prevCount != count:
prevCount = count
messageCell.setString("Number of Images: " + str(prevCount))
update_copied_images(oSheet)
time.sleep(1)
def update_copied_images(oSheet):
originCell = oSheet.getCellByPosition(COLUMN_A, FIRST_ROW)
originString = originCell.getString()
messageCell = oSheet.getCellByPosition(COLUMN_B, FIRST_ROW)
if len(originString):
messageCell.setString("originString '" + originString + "'")
else:
messageCell.setString("originString length is zero")
g_exportedScripts = start_counting_images,
To run, go to Tools -> Macros -> Run Macro, find the .py file under My Macros where you put this code, and run start_counting_images.

Powerbuilder modify row columns

I have more rows. And i want for the rows with status AA1 a column protected and for the rows with status different than AA1 the same column unprotected.
So I wrote this:
ll_count = dw_list.RowCount()
if ll_count > 0 then
for i = 1 to ll_count
if dw_list.object.status[i] = 'AA1' then
dw_list.modify("f_change[i].Protect='1")
//dw_list.Object.f_change[i].modify("f_change[i].Protect='1")
dw_list.Object.f_change[i].Background.Color = gf_get_btnface()
end if
if dw_list.object.status[i] <> 'AA1' then
dw_list.modify("f_change[i].Protect='0'")
end if
next
end if
But dw_list.modify("f_change[i].Protect='1'") is not correct. Neither dw_list.Object.f_change[i].modify("f_change[i].Protect='1").
If I just write dw_list.modify("f_change.Protect='1'") it modifies all the rows.
I woud do this without programming a single line, but by editing the datawindow design.
Open the datawindow in design mode
Select the desired column
In the 'General' tab, click on the small icon nearby 'Protect'.
Insert there the condiction to protect or not that column: if( status = 'AA1', '0', '1')
Done for all your data.
The same process can be applied to many characteristics of data window columns (color, background color, visible, pointer, position,...)
Alternatively, you could put the condition programmatically, but I would only do it if you need to change the protection scheme 'on the fly'. Anyway, the principle is to set the protect condition on the column itself.
Generally speaking, try to do in PowerBuilder as much as you can WITHOUT script programming. U

OpenOffice.org/LibreOffice Calc macro: is a cell's content currently overflowing?

I have a bunch of cells whose font size I'd like to tweak if their content is overflowing, until it all fits. I'd like to write a macro to do this, unless there's a conditional formatting or other formulaic way of doing it. Is there a property that tells whether a cell is overflowing? If so, what is it?
'open office 3
'get current document
oDoc = ThisComponent
' get first work sheet
oSheet = oDoc.getSheets().getByIndex(0)
'first cell in the work sheet
Cell = oSheet.getCellByPosition(0, 0)
MsgBox Cell.CharHeight
Happy Coading :))

How do I access a member tab of a QTabWidget class by using a variable name?

In a function I am currently working on, I am creating a multi-dimensional array of checkboxes, with the dimensions specified at run-time by the user. In order to represent the 'z' dimension, I create multiple tabs -- each one representing a different dimension -- and create an array of check boxes in each tab. The tabs are labeled dim1, dim2, dim3, ... etc.
The problem I am having is the fact that in order to create the array of check boxes (within 3 'for' loops), I have to call the tabs as follows:
checkBoxVector.append(new QCheckBox( ui->dim1 ));
Where checkBoxVector holds pointers to the checkboxes. Now my first thought was that I would simply create a variable name that would change with each loop. With each iteration, it would go: "dim1", then "dim2", "dim3", ... etc. The problem with this is that I cannot reference the tabs with a string variable, I must type in the actual name of the tab. Here is a sample of that code:
int num = k+1;
QString dim = "dim";
QString tab_name = dim.append(QString("%1").arg(num));
checkBoxVector.append(new QCheckBox( ui->tab_name ));
This gives me the error " 'class Ui::MainWindow' has no member named 'tab_name' ".
Therefore; my question is: how can I apply this idea of changing the NAME of the tab with each loop, without causing such an error?
EDIT: I think I forgot to mention that the tabs have already been created at this point, and have already been labeled with the "dim1", "dim2", "dim3", ... names. The only issue I am having is how to reference these tabs after they have been created. I feel like there is a simple syntax solution.
Store the pointers to tabs in an array and index it with the variable that you use for iterating over the third dimension of your multidimensional array of checkboxes, your code would look something like this:
QTabWidget* tabs[3];
tabs[0] = ui->dim1;
tabs[1] = ui->dim2;
tabs[2] = ui->dim3;
// ... and then
checkBoxVector.append(new QCheckBox( tabs[z] ));
Someone will say it better (there is a concept name for that) but you can't dynamically declare members in c++ ... if you want QString tab_name content to be in any way related to a member of ui in this part of code:
QString tab_name = dim.append(QString("%1").arg(num));
checkBoxVector.append(new QCheckBox( ui->tab_name ));
The compiler need to know at compile time witch member of ui it will use to find the parent of the the new QCheckBox.
Correct me if I am wrong, you have dimz tabs and dimy*dimx QcheckBox in each tabs. You don't know any dim* when you build you ui file ?
So create your own widget (QWidget) it will store an array of QcheckBox* that you can dynamically create in constructor for example. This widget will take care of the proper layout of the check boxes.
Then finally you create you own QTabWidget that will create dimz tabs of your widget. You will access your tabs with their indexes corresponding to their z coordinate.
You're trying to reference a member variable that does not exist:
int num = k+1;
QString dim = "dim";
QString tab_name = dim.append(QString("%1").arg(num));
checkBoxVector.append(new QCheckBox( ui->tab_name ));
The error is caused by the fact that you are passing a non-existing member variable to the constructor of QCheckBox. The object the ui pointer is pointing to has no member variable named tab_name. If I understood your description correctly, just pass the local variable tab_name to the QCheckBox constructor like this:
checkBoxVector.append(new QCheckBox( tab_name ));