Access writng to wrong row number - ms-access

4150
NRrows = RSNonResourceCosts.RecordCount ' Number of Rows in Non Resource Table
NRCols = RSNonResourceCosts.Fields.Count ' Number of Fields in NonResource Table
Dim CL(1 To 10) As Integer ' This is to count "filled rows" when spreadsheet is filled
Dim Header(1 To 10) As String
'-----------
'Find the Headers (Taken from Actual Table and not predefined as original)
For Each Recordsetfieldx In RSNonResourceCosts.Fields
If C > 0 Then
Header(C) = Recordsetfieldx.Name
End If
C = C + 1
Next Recordsetfieldx
4170
R = 0
'Write to worksheet
RSNonResourceCosts.MoveFirst
Do Until RSNonResourceCosts.EOF
For C = 1 To NRCols - 1
FieldName = RSNonResourceCosts.Fields(C).Value
If RSNonResourceCosts.Fields(Header(C)).Value <> "" Then
CL(C) = CL(C) + 1
WKS.Cells(200 + R, C) = RSNonResourceCosts.Fields(Header(C)).Value
End If
Next C
RSNonResourceCosts.MoveNext
R = R + 1
Loop
I attach code. Have solved part of original by defining Recordset. User can add column to Table. First part of code determines the headers. Second part determines values and writes to worksheet. The new Rows are appearing first on the worksheet and in wrong column. I tried attaching worksheet but it looked awful. Any help would be appreciated.

Two things:
1) The order your records is the order they are in the recordset. If you want them in a particular order, try sorting them (perhaps with an ORDER BY in the underlying SQL statement)
2) For the column issue: In the first bit of code, I don't see where C is initialized, but keep in mind the Headers and Fields both start with an index of 0, so if you set Header(1) = the first field's header (index 0), but then copy the data in the fields without shifting the index value, it will shift everything over by one column.
As an added note, you might want to consider what happens when you have more than 10 columns. Using fixed-length arrays means your code will break. You might want to read about using a dynamic array and ReDim.

I don't yet feel like I have completely grasped the entirety of the problem yet, but let me take a stab at it. From what I do understand, data is being written from your record set into excel (good), but it is going into the 'wrong row' (question title) and the 'wrong column' (question text).
From what I see, I don't know the purpose of FieldName = RSNonResourceCosts.Fields(C).Value, but I want to make sure that you understand that RSNonResourceCosts.Fields(C).Value is not necessarily equivalent to RSNonResourceCosts.Fields(Header(C)).Value. More than that, you are likely missing at least one column altogether in your output, or at least skipping over it accidentally. rs.Fields(0).name is the first 'column' in a recordset, but it is completely ignored in your code. Perhaps this is intentional, maybe it is a key field or something useless to you, but it is important that you are making that distinction intentionally. But, since I don't see where your code populates the headers in your worksheet, I wonder if 'wrong column' means every record has been shifted a column and your last column is sitting empty. That, coupled with the dubious omission of C being initialized as 0 (not 1, or anything else) in your above code, makes me concerned that Header(3) could possibly by field(1), or field(4), or I don't know. That would certainly also confuse the columns in your output, or at least make dependence on FieldName frustrating.
Another thing, really a shot in the dark: NRrows. I have had issues before, depending on how I create my recordset, of not getting the correct record count the first time. And, if I base the population of a worksheet, array, etc., on the number of rows and the records relative position in that number, my records get all sorts of wacky. Maybe you did this already, but since it isn't shown, I recommend a RSNonResourceCosts.movelast: RSNonResourceCosts.movefirst line before you define NRrows, just to be sure.
And last, if I am way off base here... then you really are going to have to show us the spreadsheet, even if it isn't your most beautiful work. We all know that if it were, you wouldn't be asking about it here... so set your pride aside, and be more specific as well as show us what the output looks like and how it should look.

Related

Indexeddb sorting with multiple indexes

I have a file object store by indexing name and library_id like below,
let objectStore = db.createObjectStore('file', { keyPath: 'id' });
tempStore.createIndex('nameLibId', ['attributes.name', 'attributes.library_id'], { unique: false });
The object store contains multiple library id's files. I'd like apply the name sort to the particular library id's files. I tried indexing in the below format but it returns empty data.
let self = this,
db = get(self, 'db'),
transaction = db.transaction(["file"], "readonly"),
objectStore = transaction.objectStore("file"),
index = objectStore.index('nameLibId'),
keyRange = IDBKeyRange.only('library_id')),
req = index.getAll(keyRange);
req.onsuccess = ((e)=>{
console.log(e.target.result); // returns empty array
});
Attached the screenshot of db model for reference.
24536475, abc, created, jhgf and lastmodified file names are belongs to a library id called 123.
Screen Shot..* file names are belongs to an another library id called 234.
I need the files which are sorted by name only the given library id. Any help would be highly appreciated.
If your index is based on a properties array and you want to match something using IDBKeyRange.only, then your parameter to IDBKeyRange.only should also be an array. Right now you are comparing a basic string value against a properties array value, where of course nothing matches. In other words, you cannot query against a two-part array using only one part of it.
Furthermore, the parameter to IDBKeyRange.only isn't a property name, it is a value. You want to specify a value to match in the index's set of keypath values. For example, if your index was based exclusively on attributes.name, then you would want to specify a particular value within that index, such as "abc".
And so, taking into account the above two points, and given that your index is not a single value but is instead an array of two properties, you need to revise your parameter to IDBKeyRange.only to look for an array. Something like IDBKeyRange.only(['abc', 'yoktc....']);.
Now, this is further complicated by the fact that what you are doing in your code does not actually accomplish what you want. Ignoring the sort concern for a moment, you only want to use the id condition, and not the name, when matching rows of this index. So you might be tempted to try IDBKeyRange.only([undefined, 'asdf']). Unfortunately this will not work at all because you cannot specify undefined (you will get a javascript error).
So, you must always query by both values, even though you only want to apply criteria to one of the values. The trick here is that you switch to using a different method than only. You use IDBKeyRange.bound(), and furthermore, you do a trick where you specify a criteria such as "smallest possible number is less than my number and my number is less than largest possible number", e.g. a condition that always is true. You use "smallest possible value" as your lower boundary, and "largest possible value" as your upper boundary.
Here is an example in your case. The smallest possible value of name I think is empty string. The largest possible value of name is probably any non-alphanumeric character, so let's use tilde "~". So, now we would rewrite the range parameter. Instead of using IDBKeyRange.only, we use IDBKeyRange.bound. It looks like the following (roughly):
var libId = ???;
var smallestNameValue = '';
var largestNameValue = '~';
var lowerBound = [smallestNameValue, libId];
var upperBOund = [largestNameValue, libId];
var range = IDBKeyRange.bound(lowerBound, upperBound);
Now, the second part, regarding sorting, and a major caveat of using indices that have multiple parts (not to be confused with the multiPart index property, ugh). And I myself get this backwards all the time, so I might even be wrong here and the above will work. The problem with the above is that one the first criterion is met the second is ignored, because of how the short-circuited array sorting algorithm works in indexedDB's comparison function. Your query is going to match everything, because every index row meets the criteria. So the trick to this is to always query first by the important condition, to basically pay attention to the order in which you specify your conditions. So what that means is that you need to switch the order of the properties you specified when creating the index, so that you can query first by libId and then by name.
Instead of createIndex('nameLibId',['attributes.name','attributes.library_id']); you want to do createIndex('nameLibId',['attributes.library_id', 'attributes.name']);. And this also means you need to swap your lower and upper bound queries, e.g. var lowerBound = [libId, smallestNameValue]; (and don't forget to switch the upper).
As I mentioned in my answer on using compound indices, you can always using indexedDB.cmp to experiment. Right now, open up the console on this web page. In the console, type something like this:
indexedDB.cmp(['', '5'], ['~', '5']);
Take a look at the results.
Some final notes:
Tilde might be the wrong thing to use, sorry but I am not bothering to remember, you could also just try any valid sentinel value, where by sentinel I mean any value you know will always come after all your other valid values
As I point out in my other answer, if either prop is missing in the data the actual object won't match
for cmp, -1 means left is less than right, 0 means left equals right, and 1 means left greater than right

how to retrieve data from a column and produce that value into a new column

I'm super new to R and have a question on how to do something. I listed the things that i got to work so ppl have an idea on what is going on. the thing im having trouble with is in bold.
-I have a data spreadsheet with 2 columns of data (End and CTCF). With the CTCF column having more cells
-I want to to take one value from the "End" column and subtract that value from each individual value in "CTCF" column (so i would have a bunch of products from each calculation)
-I want to then compare those products and find the miniumn absoulute value and the coresponding spot in the CTCF column
-then place that value into a new column ajacent to the corresponding End value.
I wrote a while loop (i know there is probably a WAY easier method) and got the calulation/comparison thing down. I was even able to output the location of the CTCF cell that contains my value of interest see below:
*
*data2<-read.csv("farah.csv")
head(data2)
periph_ctcfs<-list()
temp<-vector(mode="numeric", length = 356)
count<-1
for(i in 1:length(data2$CTCF)) while (count<357)
{
End<-data2$End[count]
periph_ctcfs<-(End-data2$CTCF)
periph_ctcfs<-abs(periph_ctcfs)
periph_ctcfs<-which.min(periph_ctcfs)
print(periph_ctcfs)
temp[]<-data2$CTCF[periph_ctcfs]
count<-count + 1;
}*
The problem is when im trying to produce the new "periph_ctcfs" column, when im trying to insert it into the "temp" vector, the last printed number gets placed within all the cells of the "temp" vector. It feels like that each time the loop goes through its not inserting the retrieved value into "temp". Can anyone help? Thanks ive included a link to a photo (below) so you can get a visual on the layout of the data. Sorry for being a n00b.
For clarity purposes:

Only Show specific word from a string

I'm currently learning Access 2016 since i find it works wonders with Excel.
However i'm trying to find the correct SQL code for detecting certain words in Long Text and only output these words not the text itself
Here is the setup
Fieldname: Type
Long Text
Cell Information
Cell1: Johan have a nice car
Cell2: Jane road a bike.
Cell3: Janes bike was red
Output
Cell1: car
Cell2: bike
Cell3: bike
I'm only interested in keeping certain words from these strings when the query is done, and they should be output to the same Fieldname, i have tried to locate this information for the most part of the day and my last hope of sanity was to check in here if someone has an idea of which function i should be using.
Thank you for your time
You will probably have to use VBA for this, depending on how big your list of words is, but one way to do it with SQL, assuming a relatively small and FIXED list of words:
IIF(<Mytext> LIKE '*car*','car',IIF(<Mytext> LIKE '*bike*','bike',''))
You could either read the values from a table or fill an array. Both would work, but I prefer table-driven code because, for something like this, adding new search terms would only require you to add them to your table.
So, what I would do is first create a new table called tblSearchTerms. In that table, create one field called SearchTerms, and put each of your terms (i.e. "Car", "Bike", etc...) in there, one per record.
Then set up a function in Access. Open a Module (either a new one or one you already have, as long as it's a Module), and enter this:
Function SearchExists(sString As String) As String
Dim db as Database
Dim rec as Recordset
Set db = CurrentDB
Set rec = db.OpenRecordset("Select SearchTerms from tblSearchTerms")
Do while rec.EOF = False
If InStr(1, sString, rec(0)) > 0 Then
SearchExists = "" & rec(0) & ""
Goto BugOut
Else
End If
Loop
SearchExists = "Not Found"
BugOut:
End Function
Now, what you do is create a query. In that query, you'll have one field to check to see if your search term exists. It will look something like this:
MySearchTerm: SearchExists([Cell1])
When you run your query, that field will either populate with one of the search terms (if it's found), or will return "Not Found".
This may require a bit of tweaking, because it's more for finding a search term in an Access table, so there's going to need to be some adjusting to make it work with Excel, but it's pretty close to what you need.

InStrRev Not Giving Correct Results

I have an Access database where I'm importing book/journal publication data from JabRef in a CSV format.
When I import the data to Access one of the odd things that happens is that the page numbers are given two hyphens in between them, so the data in the "pages" column in Access would look something like "200--213"
I need to be able to count the number of pages that are referenced.
In order to do this I do the following in unbound text boxes on the form:
I find the length of the string in the "pages" column (have to rename the pages variable as it's a reserved name to pagesset): PLen = Len([pagesset])
I find the number of characters that happen from the left up to the "--": LPageVar = InStr([pagesset],"--")
I find the number of characters that happen from the right up to the "--": RPageVar = InStrRev([pagesset],"--")
I find the actual page number on the left side of the "--": LVal = Left([pagesset],[LPageVar]-1)
I find the actual page number on the right side of the "--": RVal = Right([pagesset],[RPageVar]-1)
I calculate the number of pages that appear: Pgcnt = RVal - LVal
Everything seems to work... except when the "InStrRev" hits an item that increments the number by the 10 or 100 spot, like this: "7--11", "7--23", or "92--101" as opposed to this: "102--123" or "103--110" (which causes no issues). When it hits these shorter pagethe RPageVar is too low by 1.
For each of these items on the right, RVal seems to drop the first character... so for "7--11" last page is reported as 1 or for "7--23" it would report the last page as 3 or "92--101" the last page is reported as 01. This causes these particular page counts to be negative.
Does anyone have an idea as to why I'm getting this behavior?
InStrRev() searches from the end of the string, but the location it returns is relative to the beginning of the string, not the end. So,
s = "this is a test--1"
Debug.Print InStrRev(s,"--")
displays 15, and
Right("this is a test--1",15)
is obviously not going to isolate the "1" at the end of the string. That would be done with
Mid(s,InStrRev(s,"--")+2)
or, in the case where there is only one instance of "--" in the string
Mid(s,InStr(s,"--")+2)
would also work.
Here is a different approach which is less confusing for me; not sure if it will be less confusing for anyone else, though.
? PageCount("200--213")
14
? PageCount("7--11")
5
Function PageCount(ByVal pIn As String) As Long
Dim astrPageRange() As String
astrPageRange = Split(pIn, "--")
PageCount = (Val(astrPageRange(1)) - Val(astrPageRange(0))) + 1
End Function

Multiple appearances of a name in a SharePoint list, but need only one for BIDS report

I'm building a report in BIDS based on a SharePoint list. I want to make a multi-valued parameter to filter the list by a name, but each name shows up multiple times in the list. The report is already going to be filtered by work site, and I need this filter in addition. I'm pretty new to SSRS, so there may be a simpler solution, but I've thought of two ways this could be done, though neither is particularly efficient.
One way is to create a separate MVP for each site, and manually write out each name for that site in the parameter's Available Values. The problem is that I don't think there's a way to hide a parameter based on which site you're looking at; for instance, if I'm looking at Site A, the drop-down lists for Sites B-Z would all also show up. They wouldn't do anything, since the superfluous sites would already be filtered out, but it'd be an eyesore. This approach would also be difficult to maintain in the long-run, requiring someone to come in and manually add every new name to the parameter.
The other, better approach is to add a new dataset with only names and site IDs, and find some way to filter out every repetition of a name, so all that's left is the name and the associated site. I have no idea how this could be done, though.
Finally found an explanation: http://blogs.msdn.com/b/sqlforum/archive/2011/04/28/walkthrough-how-to-get-distinct-values-of-a-column-of-a-sharepoint-list-using-sql-server-reporting-services.aspx
Essentially, this has you create one parameter to serve as a sorta jury-rigged dataset based on a piece of custom VB code. That first parameter is then used to populate a second, multi-valued parameter, which contains all unique values.
The VB code:
Public Shared Function RemoveDuplicates(parameter As Parameter) As String()
Dim items As Object() = parameter.Value
System.Array.Sort(items)
Dim k As Integer = 0
For i As Integer = 0 To items.Length - 1
If i > 0 AndAlso items(i).Equals(items(i - 1)) Then
Continue For
End If
items(k) = items(i)
k += 1
Next
Dim unique As [String]() = New [String](k - 1) {}
System.Array.Copy(items, 0, unique, 0, k)
Return unique
End Function
NB: When you set up the dataset in this process, make sure to alter the query to reflect your own data source; don't just copy/paste blindly.