I'm creating an Excel file using ColdFusion and POI Workbook. The file is created great, however I have cells that contain numeric values and need to be stored as numbers for SUM and other functions to work properly.
I want to call code after the data has been added for the excel sheet that will basically loop over the data, and if the value is numeric, set the data format as numeric. That way when I open the Excel file, I can perform a SUM or whatever on that column of data.
Below is what I've tried so far, and it does "work" because all the cells have the #EBEBEB background color, however they still have the warning that says "Number stored as text" as seen below. How can I fix this?
// Create our dataFormat object
df = poiWorkbook.createDataFormat();
// Create our new style
formatNumber = poiWorkbook.createCellStyle();
formatNumber.setFillPattern( formatEvenRowRightAlignStyle.SOLID_FOREGROUND );
formatNumber.setAlignment( formatNumber.ALIGN_RIGHT );
XSSFColor = createObject("java", "org.apache.poi.xssf.usermodel.XSSFColor");
formatNumber.setFillForegroundColor( XSSFColor.init(Color.decode("##EBEBEB")) );
formatNumber.setDataFormat(df.getFormat("0.00"));
// Loop over the data and apply the format
for (x=0;x<rowCount;x++) {
for (y=0;y<colCount;y++) {
poiSheet.getRow(x).getCell(y).setCellStyle(formatNumber);
}
}
(Promoted from comments ...)
call code after the data has been added
Any reason why? While it is possible, it is simpler, and less error prone, to format while populating the sheet. Assuming the query column data type is numeric (not varchar or something), you should be able to call SpreadsheetFormatColumn for that column, after adding the query data.
Having said that, the fact that you are getting "Number stored as text" warnings in the first place makes me wonder about the data type of your query column. IIRC, later versions of CF should detect numeric columns when SpreadsheetAddRows is used, and apply a numeric format to those columns automatically. Is it possible your query column is being formatted as a string instead of some numeric type? As that would explain the results. The solution is to cast the column to a numeric type inside the db query.
Related
I've got a table full of different data types, including records, that I want to extract all column names of records to then use in an expand function. I've included a screenshot of a column containing record's however, when I use this = Table.ColumnsOfType(#"Expanded fields", {type record}), it returns an empty list .
I've tried looking through the entire column to see if there was anything different but its all record types. Any help please.
EDIT:
Error using Table.TransformColumnTypes
Record is not a valid type to search for. And judging by your image, your type is Type.Any as denoted by the ABC123
You best bet is to unpivot all the columns (perhaps those starting with a certain prefix) then on the new Value column, expand like so
#"PriorStepNameHere" = .... ,
ExpandList= List.Distinct(List.Combine(List.Transform(Table.Column(#"PriorStepNameHere", "Value"), each if _ is record then Record.FieldNames(_) else {}))),
Expand= Table.ExpandRecordColumn(#"PriorStepNameHere", "Value", ExpandList,ExpandList)
It sounds like the Table.ColumnsOfType function is not properly identifying the columns in your table that contain records.One possible reason for this is that the column's datatype is not properly set as 'record'. Another possible reason could be that the data in the columns is not structured properly and hence it is not being identified as a record. You can try to use the Table.TransformColumnTypes function to convert the column's datatype to 'record' and see if that resolves the issue.
If the issue still persists, please share the sample data and the code you are using.
I have to read data from recordset for one coloumn whose datatype is text. Below mentioned is the syntax:
VARIANT vProps = rs->Fields->GetItem("Props")->GetValue();
Here, "Props" is the name of the column which contains the xml data in text datatype. When I tried to get the value in vProps it returns some invalid value and data is not populated in variant.
I have saved the content of the column field in a .xml file and file loaded properly. Please note the size of the file is 74kb.
Likewise there are other entries also in database table for "Props" column, however in case when size is less than 10 KB, variant populated successfully using the same piece of code.
Is there any limitation to VARIANT datatypes size ?
How to fix this issue.
Thanks in advance.
Microsoft has defined limitations on the maximum sizes and numbers of various objects defined in SQL Server components.
For example,
Bytes per short string column: 8,000
So I want to make a table in MYSQL (using c++) with about 128 columns each on representing an INT.
I don't know the syntax to make a 129 column row (1 for id 128 for each int)
Kinda like an array: int myArray[128];
CREATE TABLE SIFTFEATUES(ID INT not null, myArray[128] INT) would be Ideal or something close
where I don't have to write out each column name.
To have a table with 128 columns defined, you need to "write out" each column name. Each column in the table gets a name, a datatype, and other optional attributes.
In order to retrieve data from the column, it has to be referenced by name; the same is true for inserting and updating the contents of the column.
(I put "write out" in double quotes, because it's very simple task to generate a text file of 128 lines of a table definition that vary only by name. (It's not necessary to type each line.)
, col001 int
, col002 int
, ...
, col128 int
Absent any other information about your use case, what you are trying to accomplish, it's nearly impossible to make any sort of recommendation.
A table should be use for data persistence, thus not to be used like an array (with obvious exceptions). With that said I see two scenarios:
1) You want to use it like a temporary data structure, which I strongly do not recommend, unless for medical reasons.
2) You want to keep that table, for which I'd use a text editor or even MS Excel and create a macro to create the CREATE TABLEstatement with your 128 columns.
Say I have a query like the one below. What would be the best way to put each value into an array if I don't know how many results there will be? Normally I would do this with a loop, but I have no idea how many results there are. Would I need run another query to count the results first?
<CFQUERY name="alllocations" DATASOURCE="#DS#">
SELECT locationID
FROM tblProjectLocations
WHERE projectID = '#ProjectName#'
</CFQUERY>
Depending on what you want to do with the array, you can just refer to the column directly for most array operations, eg:
i = arrayLen(alllocations["locationID"]);
Using that notation will work for most array operations.
Note that this doesn't "create an array", it's simply a matter that a query columns - a coldfusion.sql.QueryColumn object is close enough to a CFML array for CF to be able to convert it to one when an array is needed. Hence the column can be passed to an array function.
What one cannot do is this:
myArray = q["locationID"];
This is because by default CF will treat q["locationID"] as a string if it can, and the string value is what's in the first row of the locationID column in the q query. It's only when an array is actually required will CF convert it to an array instead. This is basically how loose-typing works.
So if you just need to pass your query column to some function that expects an array, you can use the syntax above. If you want to actually put the column into a variable, then you will need to do something like this:
myArray = listToArray(valueList(q.localtionID));
NB: make sure you use <cfqueryparam> on your filter values instead of hard-coding them into your SQL statement.
myquery.column.toArray() is also a good undocumented choice.
Since you're only retrieving 1 field value from the query, you could use ValueList() to convert the query results into a comma-delimited list of locationIds, then use listToArray() to change that list into an array.
If you were retrieving multiple field values from the query, then you'd want to loop through the query, copy all the field values from the given row into a struct, and then add that struct to an array using arrayAppend().
(If you're not familiar with these functions, you can look them up in the Adobe docs or on cfquickdocs.com).
I'm attempting the use QuerySetCell to change value of a specific column in a query object, and have been receiving this error:
Column names must be valid variable names. They must start with a letter and can only include letters, numbers, and underscores.
The reason for this error, and the complication here, is that the columns I am trying to update have some integers as names, taken from a separate record's key/ID. For example, the query may contain three columns with names: "6638, 6639, 6640".
Now, I understand why this error is occurring (though not necessarily why CF has this limitation), however cannot come up with a work around. The further complications are that I cannot make any changes as to how the initial query set's column names, and need to preserve the column names and their order for when I convert the query to a JSON string and update my results table using the JSONified query.
Has anyone encountered this issue before, and if so how were you able to work around it, or were you forced to change how the columns were named in your initial query?
Using CF8 and have the ability to edit the JSONified query after it is returned from my Ajax handler if that makes a difference.
You can use bracket notation to set the values in a query (at least you can in CF9 - I do not have CF8 installed to test).
The sytax is pretty simple:
<cfset queryName[columnName][row] = "some new value" />
From your example, you could use this:
<cfset myQuery["6638"][1] = "moo" />
This will set the value of the '6638' column in the first row to 'moo'. If you have multiple rows being returned, you would need to set each row.