I am working on the heritage codes which use C++ Excel Automation to output our analysis data in the excel spreadsheet. From the following article,
https://support.microsoft.com/en-us/topic/how-to-use-mfc-to-automate-excel-and-create-and-format-a-new-workbook-6f2450bc-ba35-a36a-df2f-c9dd53d7aef1
I knew we can use "range.SetFormula() function to calculate the formula results from some specific cells, for example:
range = sheet.GetRange(COleVariant("C2"), COleVariant("C6"));
range.SetFormula(COleVariant("=A2 & \" \" & B2"));
My question here is how can I use SetFormula function to point to some cell elements whose row & column are unknow but will be determined as the program runs. In specifically, I have a number of cell elements populated as my analysis runs. Different analysis will have different number of elements output to the excel spreadsheet. For example, if I have kw data, then the excel output will be populated in kw row 6 column and I also need to output some summary results based on these element underneath these populated elements. Something like this:
int kw = var_length; // the row changes depending on different analysis
DWORD numElements[2];
Range range;
range = sheet.GetRange(COleVariant(_T("A3")),COleVariant(_T("A3")));
numElements[0]= kw; //Number of rows in the range.
numElements[1]= 6; //Number of columns in the range.
saRet.Create(VT_R8, 2, numElements);
for(int iRow = 0;iRow < kw; iRow++)
{
for (iCol = 0; iCol < 6; iCol++)
{
index[0] = iRow;
index[1] = iCol;
saRet.PutElement(index, &somevalue);
}
}
range.SetValue2(COleVariant(saRet));
CString TStr;
TStr.Format(_T("A%d"), kw+2);
range = sheet.GetRange(COleVariant(TStr), COleVariant(TStr))
CString t1, t2;
t1.Format(_T("A%d"), kw/2);
t2.Format(_T("A%d"), kw);
range.SetFormula(COleVariant(L"=SUM(A&t1: A&t2)")); // Calculate the sum of second half of whole elements, Apparently, this didn't work, How can I fix this?
Here I want to sum the second half of whole elements but in the SetFormula function, I didn't know exactly row number for these element, eg, A25 - A50. The row number is dependent on the kw which is given as input from program. Different analysis, kw is different. I attempted to use TStr format to get the row number but it CAN NOT be used inside SetFormula function. Ideally I want to use formula for my summary data output so that if I change my populated the element values, the summary data output can change accordingly. I searched in your MSDN website but couldn't find any solution on how to resolve this.
Can someone help me with the issue?
Thanks in advance.
I have an existing Word document containing a table. The first row of the table has two cells, but all the other rows have four cells and each cell has a different width.
I need to insert new rows via POI that also have four cells with widths that match those of the existing 4-cell rows.
The basic code is:
XWPFTable table = doc.getTableArray(0);
XWPFTableRow oldRow = table.getRow(2);
table.insertNewTableRow(3);
XWPFTableRow newRow = table.getRow(3);
XWPFTableCell cell;
for (int i = 0; i < oldRow.getTableCells().size(); i++) {
cell = newRow.createCell();
CTTblWidth cellWidth = cell.getCTTc().addNewTcPr().addNewTcW();
BigInteger width = oldRow.getCell(i).getCTTc().getTcPr().getTcW().getW();
cellWidth.setW(width); // sets width
XWPFRun run = cell.getParagraphs().get(0).createRun();
run.setText("NewRow C" + i);
}
The result of this is that row 3 has four cells but their widths do not match those of row 2. The total new row width ends up being the same as the total width of the first three cells of row 2. (Sorry, I don't know how to paste the Word table here).
However, if I first manually edit the source document so that the first table row also has four cells, then everything works perfectly. Similarly, if I get a reference to an existing row and add it to the table, then the cell widths are also correct (but I have the same row object twice so can't modify it).
It seems that the number of cells in the first row influences how other rows are inserted. Does this make sense to anyone and can you suggest how to override it? Also, is there a document anywhere that I can study to understand how this works? Thanks.
Accordiing to your mention: "The first row of the table has two cells, but all the other rows have four cells and each cell has a different width." I suspect this will be a very messy table. Although Word is supporting such tables, I would try to avoid such. But if it must be, you need to know that there is a table grid also for those messy tables. Unzip the *.docx and have a look at /word/document.xml there you will find it.
So if we want to insert rows into such messy tables, we also must respect the table grid. For this there is a GridSpan element in the CTTcPr. This we must also copy from the oldRow and not only copy the CTTblWidth.
Also the CTTblWidth has not only a width but also a type. This we also should copy.
Example:
The source.docx looks like this:
As you see the table grid has 10 columns in total. "Cell 2 1" spans 3 columns, "Cell 2 2" spans 3 columns, "Cell 2 3" spans 0 columns (is its own column), "Cell 2 4" spans 3 columns.
With code:
import java.io.*;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblWidth;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr;
import java.math.BigInteger;
public class WordInsertTableRow {
public static void main(String[] args) throws IOException, InvalidFormatException {
XWPFDocument doc = new XWPFDocument(new FileInputStream("source.docx"));
XWPFTable table = doc.getTableArray(0);
XWPFTableRow oldRow = table.getRow(2);
table.insertNewTableRow(3);
XWPFTableRow newRow = table.getRow(3);
XWPFTableCell cell;
for (int i = 0; i < oldRow.getTableCells().size(); i++) {
cell = newRow.createCell();
CTTcPr ctTcPr = cell.getCTTc().addNewTcPr();
CTTblWidth cellWidth = ctTcPr.addNewTcW();
cellWidth.setType(oldRow.getCell(i).getCTTc().getTcPr().getTcW().getType()); // sets type of width
BigInteger width = oldRow.getCell(i).getCTTc().getTcPr().getTcW().getW();
cellWidth.setW(width); // sets width
if (oldRow.getCell(i).getCTTc().getTcPr().getGridSpan() != null) {
ctTcPr.setGridSpan(oldRow.getCell(i).getCTTc().getTcPr().getGridSpan()); // sets grid span if any
}
XWPFRun run = cell.getParagraphs().get(0).createRun();
run.setText("NewRow C" + i);
}
doc.write(new FileOutputStream("result.docx"));
doc.close();
System.out.println("Done");
}
}
The result.docx looks like:
I have data of 100 x 101. I want to convert them in series e.g. for first row all column data then for 2nd row all column data and so on. It means the result will be three columns only. The first column with row numbers, the 2nd column with column numbers and the 3rd column with the value for that respective row and column.
Could you please help me doing this conversion in MATLAB.
Available data are in ASCII format and it is possible to open in both MATLAB and Excel.
This can be done by find:
A = rand(100,101);
[data(:,1), data(:,2), data(:,3)] = find(A);
data = sortrows(data,[1 2]);
Note that this is highly inefficient, as you are storing 3 values where you only need to store 1 (the element's actual value). For accessing a specific element, say row 31, column 43, you simply do A(31,43), where you index the matrix.
The file size of data is indeed three times larger than that of A:
whos
Name Size Bytes Class Attributes
A 100x101 80800 double
data 10100x3 242400 double
You can use the ind2sub function that is faster and make more sense in this situation:
tic
A = rand(100,101);
[data(:,1), data(:,2), data(:,3)] = find(A);
data = sortrows(data,[1 2]);
toc
tic
B = A' ;
[data_B(:,1), data_B(:,2)] = ind2sub(size(B), 1:length(B(:)));
data_B(:,3) = B(:);
toc
The output for the timing is as follow:
Elapsed time is 0.002130 seconds (first method)
Elapsed time is 0.000525 seconds (second method).
My fxml file has the following declaration:
< TableView fx:id="myTable" prefHeight="756.0" prefWidth="472.0" />
then in Java code, I add the columns and then setItems as usual. This works as expected.
The only other code which affects the table is:
myTable.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
which nicely automatically re-sizes the columns. But I can't figure out how to do the following:
When I add say 1 or 10 items to the table, those appear as expected in the first 1 or 10 rows of the table, but the number of rows in the table are always 21. Rest of the rows are just empty. I want the table to have only 1 row if I set 1 item or 10 rows if I set 10 items. How do I achieve this ?
All the columns are of the same size. I can manually re-size them, but I want columns to auto-fit according to their size. For example if I have 2 columns one with integer from 1-10 and another with text description, they both have equal size. How do I tell it to autofit the column size according the the row contents ?
Thanks for the response!
The table fills up the layout with empty rows. Try hiding them by adding css
.table-row-cell:empty {
-fx-background-color: -fx-background;
}
.table-row-cell:empty .table-cell {
-fx-border-width: 0px;
}
For #2 you can check the length of text in the cells in the cell value factory but I have title problems like that. You can read the data set and figure out what it should be. These are both approximations depending on font size.
Added this, my play cellValueFactory where I tried out some things.
TableColumn<LineItem,String> amountCol = new TableColumn<>("Amount");
amountCol.setPrefWidth(amountCol.getText().length()*20);
amountCol.setCellValueFactory(new Callback<CellDataFeatures<LineItem, String>, ObservableValue<String>>() {
#Override
public ObservableValue<String> call(CellDataFeatures<LineItem, String> p) {
SimpleStringProperty ssp = new SimpleStringProperty(String.format("%.4f", p.getValue().getAmount()));
amountCol.setPrefWidth(Math.max(amountCol.getPrefWidth(), ssp.get().length()*20));
return ssp;
}
});
I've been trying out the dp tutorials on Topcoder. One of the problems given for practice was MiniPaint . I think I've got the solution partly- find the minimum no. of mispaints for a given no. of strokes, for each row and then compute for the entire picture (again using dp, similar to the knapsack problem). However, I'm not sure how to compute the min. no for each row.
P.S I later found the match editorial, but the code for finding the min. no. of mispaintings for each row seems wrong. Could someone explain exactly what they've done in the code?
The stripScore() function returns the minimum number of mispaintings for each row given the amount of strokes available to paint it. Although I'm not sure if the rowid argument is correct, the idea is that starting at start at a particular row with needed amount of strokes available to use and the colour of the region directly before it.
The key to this algorithm, is that the best score for the area to the right of the kth region, is uniquely determined by the number of strokes needed, and the color used to paint the (k-1)th region.
Intuition
I have been bashing my head with this problem for 3 days straight, not realising that It requires two consecutive uses of dynamic programming logic. My approaches, in contrast to the ones available from topcoder, are bottom up.
To start with, instead of calculating the minimum number of mispaints I can achieve, I will instead calculate the maximum number of cells I can paint with maxStrokes strokes. The result can easily be calculated by subtracting my findings from the total cells of my matrix. But how can I really do that? The initial observation has to be the fact that each row can yield me some painted cells in exchange for a number of strokes. This does not depend on the rest of the rows. That means that, for each row, I can calculate the maximum number of cells I can paint on that specific row, with a certain number of strokes.
Example
Input=['BBWWB','WBWWW'], maxStrokes=3
Let's now look at the first row BBWWB, and denote C to be the Max number of cells i can paint with Q strokes
Q C
0 0 (I cant paint with 0 strokes)
1 3 (BBWWB)
2 4 (BBWWB)
3 5 (BBWWB)
We could easily represent the above results with an array of length 4 that stores for each index (stroke) the maximum number of cells that can be painted, namely [0,3,4,5]
It's easy to see that the second row in the same manner would have an array [0,4,4,5].
The result can now easily be calculated just by these two arrays alone, as what we're looking for is a combination of two choices, one for each calculated array, that will yield me the highest amount of cells I can paint with 3 strokes. What are my choices though? Each item of my array represents the maximum number of cells i can paint with index strokes. So, for the first array a choice would be to paint 4 cells with 2 strokes.
I could then combine that choice with the second array's 1-st item 4, which means I can paint 4 cells with 1 stroke. My final result would be 4+4=8 cells with 2+1=3 strokes, which happens to be the best I can get. The output would then trivially be 2*5-8=2 minimum mispaints. However, we need to find an optimal way to calculate the different combinations of items from each row and what sums they can yield me.
The Process
The first part of my algorithm populates two very important tables. Let us denote with N, M the dimensions of the matrix I'm given. The first table, dp is a N*M*maxStrokes matrix. dp[i][j][k] represents the maximum number of cells I can paint from the 0-th cell up until the j-th cell of the i-th row with k strokes. As for the maxPainted table, that is a N*maxStrokes matrix. maxPainted[i][k] stores the maximum number of cells I can paint in the i-th row with k strokes and is identical to the arrays calculated in the above example. In order to calculate the latter, I need to calculate dp first. The formula is the following:
dp[i][j][k]= MAX (1,dp[i][r][k]+1 (if A[i][j]==A[i][r]) ,dp[i][r][k-1]+1 (if A[i][j]!=A[i][r])), for every 0<=r<j
Which can be translated as: The maximum number of cells I can paint up to the j-th cell of the i-th row with k strokes is the maximum of:
1, because I can just ignore all the previous cells, and paint this cell alone
dp[i][r][k]+1, because when A[i][j]==A[i][r], I can extend that color with no extra strokes
dp[i][r][k-1]+1, because when A[i][j]==A[i][r], I have to use a new stroke to paint A[i][j]
It is now evident, that the dp table needs to be calculated in order to acquire the best possible scenarios for each row, that is the maximum number of cells I can paint with every possible number of strokes available. But how can I utilize the maxPainted table once I have calculated it in order to get to my result?
The second part of my approach uses a variation of the 0-1 Knapsack problem in order to calculate the biggest number of cells I can paint with maxStrokes strokes available. What really made this challenging, is that, in contrast to the classical Knapsack, I am only allowed to pick 1 item out of every row, and then calculate all the possible combinations that do not surpass the required stroke constraint. In order to achieve that, I will firstly create a new array of length N*M +1 , called possSums. Let us denote with possSums[S] the MINIMUM number of strokes needed to reach sum S. My goal is to calculate each row's contribution to this array. Let us demonstrate with our previous example.
So I had a 2*5 input, therefore the possSums array would consist of 10+1 elements, which we set to Infinity, as we re trying to minimize the keystrokes needed to reach said sums.
So, possSums=[0,∞,∞,∞,∞,∞,∞,∞,∞,∞,∞], with the first item being 0 because I can paint 0 cells with 0 strokes. What we re now looking to do is calculate each row's contribution to possSums. That means that for every row of my maxPainted array, each element needs to make a specific sum available, which will simulate it being chosen. As we have previously demostrated, maxPainted[0]=[0,3,4,5]. This row's contribution would have to allow 0,3,4 and 5 as achievable sums in my possSums array with used strokes 0,1,2,3 respectively. possSums would then be transformed to possSums=[0,∞,∞,1,2,3,∞,∞,∞,∞,∞]. The next row was maxPainted[1]=[0,4,4,5], which now has to once again alter the possSums to allow the combinations made possible with the selection of each item. Notice that each alterations needs to be irrelevant to the others in the same row. For example, if we first allow the sum=4 which can happen by picking the 1st item of maxPainted[1], sum=9 cannot be allowed by furtherly picking the 3d item of that same array, essentially meaning that combinations of items in the same row cannot be considered. In order to ensure that no such cases are considered, for each row I create a clone of my possSums array to which I will be making the necessary modifications instead of my original array. After considering all of the items within maxPainted[1], possSums would look like this possSums=[0,∞,∞,1,1,3,∞,2,3,4,6], giving me a maximum number of cells that can be painted with up to 3 strokes on the 8th index (sum=8). Therefore my output would be 2*5-8=2
var minipaint=(A,maxStrokes)=>{
let n=A.length,m=A[0].length
, maxPainted=[...Array(n)].map(d=>[...Array(maxStrokes+1)].map(d=>0))
, dp=[...Array(n)].map(d=>[...Array(m)].map(d=>[...Array(maxStrokes+1)].map(d=>0)))
for (let k = 1; k <=maxStrokes; k++)
for (let i = 0; i <n; i++)
for (let j = 0; j <m; j++) {
dp[i][j][k]=1 //i can always just paint the damn thing alone
//for every previous cell of this row
//consider painting it and then painting my current cell j
for (let p = 0; p <j; p++)
if(A[i][p]===A[i][j]) //if the cells are the same, i dont need to use an extra stroke
dp[i][j][k]=Math.max(dp[i][p][k]+1,dp[i][j][k])
else//however if they are,im using an extra stroke( going from k-1 to k)
dp[i][j][k]=Math.max(dp[i][p][k-1]+1,dp[i][j][k])
maxPainted[i][k]=Math.max(maxPainted[i][k],dp[i][j][k])//store the maximum cells I can paint with k strokes
}
//this is where the knapsack VARIANT happens:
// Essentially I want to maximize the sum of my selection of strokes
// For each row, I can pick maximum of 1 item. Thing is,I have a constraint of my total
// strokes used, so I will create an array of possSums whose index represent the sum I wanna reach, and values represent the MINIMUM strokes needed to reach that very sum.
// so possSums[k]=min Number of strokes needed to reach sum K
let result=0,possSums=[...Array(n*m+1)].map(d=>Infinity)
//basecase, I can paint 0 cells with 0 strokes
possSums[0]=0
for (let i = 0; i < n; i++) {
let curr=maxPainted[i],
temp=[...possSums]// I create a clone of my possSums,
// where for each row, I intend to alter It instead of the original array
// in order to avoid cases where two items from the same row contribute to
// the same sum, which of course is incorrect.
for (let stroke = 0; stroke <=maxStrokes; stroke++) {
let maxCells=curr[stroke]
//so the way this happens is :
for (let sum = 0; sum <=n*m-maxCells; sum++) {
let oldWeight=possSums[sum]//consider if UP until now, the sum was possible
if(oldWeight==Infinity)// if it wasnt possible, i cant extend it with my maxCells
continue;
// <GAME CHANGER THAT ALLOWS 1 PICK PER ROW
let minWeight=temp[sum+maxCells]//now, consider extending it by sum+maxCells
// ALTERING THE TEMP ARRAY INSTEAD SO MY POTENTIAL RESULTS ARE NOT AFFECTED BY THE
// SUMS THAT WERE ALLOWED DURING THE SAME ROW
temp[sum+maxCells]=Math.min(minWeight,oldWeight+stroke)
if(temp[sum+maxCells]<=maxStrokes)
result=Math.max(result,sum+maxCells)
}
}
possSums=temp
}
return n*m-result // returning the total number of cells minus the maximum I can paint with maxStrokes
}