Sequence numbers in Access 2016 - ms-access

i am trying to have a auto sequence number in a field in Access, which in case that i delete a record the number tha i will delete will apply on the next record, ex. if i have 3 records 1,2,3 and delete the 3, the next record i would like to take the 3 and not 4, i am using dmax... the code is
Private Sub Form_BeforeInsert(Cancel As Integer)
Νούμερο = DMax("Νούμερο", "Πίνακας1") + 1
End Sub
but it doesn't work. Νούμερο=field and πίνακας1=the table
thank you in advance!

It should work, but try being a little more specific:
Private Sub Form_BeforeInsert(Cancel As Integer)
Me!Νούμερο.Value = DMax("Νούμερο", "Πίνακας1") + 1
End Sub

Related

How to delete a value from a dynamic array from any position in VBA?

I have a dynamic array that I want to delete an item from. I know we can delete an item from the end of an array by decreasing its size by 1 and redimming it. But is there a way to delete an item from an array no matter what position the item is on the array?
There is no built in function to delete from a array. So, the only way is to "pull" each value down by one, and then re-dim to lop off the last value.
Arrays hark back to old days of FORTAN and early GWBASIC languages that were popular on personal computers in the late 1970's, and early 80's. Most new languages (including VBA)) have a lot better choices. Because this is a "painful" approach, then I would build a function that deletes the row for you.
This code will show how deleting works:
Private Sub Command104_Click()
Dim MyData() As Integer
Dim i As Integer
ReDim MyData(1 To 5)
For i = 1 To 5
MyData(i) = i * 100
Next i
Call MyDisplay(MyData)
' delete 3rd row
Call MyDelete(MyData, 3)
Call MyDisplay(MyData)
End Sub
Public Sub MyDelete(v() As Integer, intPos As Integer)
Dim numRows As Integer
Dim i As Integer
numRows = UBound(v)
' move every row down one
For i = intPos To numRows - 1
v(i) = v(i + 1)
Next i
' get rid of last row
ReDim Preserve v(1 To numRows - 1)
End Sub
Public Sub MyDisplay(v() As Integer)
Dim i As Integer
For i = 1 To UBound(v)
Debug.Print i, "--->", v(i)
Next i
End Sub
Output:
1 ---> 100
2 ---> 200
3 ---> 300
4 ---> 400
5 ---> 500
1 ---> 100
2 ---> 200
3 ---> 400
4 ---> 500

Access ComboBox binding and Selected Value

I am trying to create a simple form for entering data. I have two tables, jobs and reports. The report table refers to a job with a one to many (one job, many reports). When browsing through the reports I want the combo box that lists all of the jobs to show the corresponding job as the selected value. This is easy in a .NET environment, but I'm not understanding how to set this up in the property sheet for the combobox. My ComboBox record source is from a query:
SELECT Jobs.UID, Jobs.Projectcode, Jobs.Projectname, Jobs.Owner, Jobs.Contractor
FROM Jobs
ORDER BY Jobs.[Projectcode];
And the form is based on a query that joins the tables:
SELECT Report.ID, Report.ReportNumber, Report.ReportDate, Report.Temperature, Report.Weather, Report.Progress, Report.PeopleatOAC, Report.Trades, Jobs.UID, Jobs.Projectname, Jobs.Owner, Jobs.Contractor
FROM Report
INNER JOIN Jobs ON Jobs.UID = Report.JobID
UNION ALL SELECT Report.ID, Report.ReportNumber, Report.ReportDate,
Report.Temperature, Report.Weather, Report.Progress, Report.PeopleatOAC,
Report.Trades, Jobs.UID, Jobs.Projectname, Jobs.Owner, Jobs.Contractor
FROM Report
LEFT JOIN Jobs ON Jobs.UID = Report.JobID WHERE (((Report.JobID) Is Null))
ORDER BY Report.ID;
The way I have this set up, a report can have a null job field. So I want to be able to select a job from the combo box to update the report table AND I want the combo box to reflect the correct job if the current record has a jobID associated with it. Is this possible?
What I have implemented is a tie to the Current event for the form that sets the combobox value (or clears it) depending on the JobID. As well as an tied to the changed event for the combobox to update the database with a selection. This works well enough but VBA feels so limiting compared to C#, WPF, and MVVM.
For anyone stumbling accross this with a similar question here are the 2 VBA functions:
Private Sub Form_Current()
Dim JobID As Integer
Dim i As Integer
Dim TempVal As Variant
Dim TestVal As Integer
TempVal = Me.JobID.Value
If Me.JobID.Value <> Empty Then
JobID = Me.JobID.Value
Else: JobID = -2
End If
With Me.JobCodeCombo
If (JobID >= 0) Then
For i = 0 To .ListCount - 1
TestVal = .Column(0, i)
If .Column(0, i) = JobID Then
.Value = .ItemData(i)
Exit For
End If
Next
Else
Me.JobCodeCombo = Null
End If
End With
End Sub
Private Sub JobCodeCombo_Change()
Dim ReportID As Long
Dim JobID As Long
Dim dbs As DAO.Database
Dim qdfUpdateJobID As DAO.QueryDef
Dim CurrentRecord As Long
CurrentRecord = Me.CurrentRecord
Set dbs = CurrentDb
Set qdfUpdateJobID = dbs.QueryDefs("UpdateReportWithJobID")
ReportID = Me.ReportID.Value
JobID = Me.JobCodeCombo.Column(0)
qdfUpdateJobID.Parameters(0).Value = JobID
qdfUpdateJobID.Parameters(1).Value = ReportID
qdfUpdateJobID.Execute
qdfUpdateJobID.Close
DoCmd.Save acForm, "Form1"
Me.Requery
DoCmd.GoToRecord acDataForm, "Form1", acGoTo, CurrentRecord
End Sub
The query called from the second function is a simple update query in my access file that has two parameters:
PARAMETERS [P1] Long, [P2] Long;
UPDATE Report SET JobID = P1
WHERE [ID] = P2;

Inserting a cell in excel based on cell value

I am working on exporting CSVs of large groups from an active directory environment. Many of these groups have extensive nesting and I need to insert cells so that the worksheet is human readable.
For example my worksheet looks like this:
WS Example
Int User Path
0 User1 CN
0 User2 CN
1 User3 CN
1 User4 CN
0 User5 CN
1 User6 CN
2 User7 CN
I am looking for help adapting a VBA script that reads the integer value from the first column and inserts the corresponding number of cells to the left of the column for that particular row. The constraint is that the list cannot change the order of the rows so as to preserve the nested structure.
Here is what I have in VBA so far
Sub test()
Dim d As Integer
d = Range("A:A").End(xlDown).row
Dim c As Range
For i = d To 1 Step -1
If Cells(i, 1).Value Like "1" Then
Rows(Cells(i, 1).Column).Insert shift:=xlShiftRight
End If
Next
End Sub
Currently this snippet counts the number of 1's from the column and inserts a new row at the top of the list. I believe the error in my logic is within the If statement and once I have that ironed out I know I can expand that with an ElseIf to address the rest of the values.
This will do it. The issue looks like it's within the line Rows(Cells(i, 1).Column).Insert shift:=xlShiftRight. If you break that down, it computes as follows:
Cells(i,1).Column which equals 1, since the column of .Cells(i,1) is 1.
Rows(1) the 1 comes from the above. So Rows(1) is 1.
Rows(1).Insert inserts above row 1, regardless of what you specify for shift.
Sub test()
Dim d As Integer
d = Range("A:A").End(xlDown).row
Dim c As Range
For i = d To 1 Step -1
If Cells(i, 1).Value Like "1" Then
Cells(i, 1).Insert shift:=xlToRight
End If
Next
End Sub
This should do it.
Sub test()
Dim d As Integer
d = Range("A:A").End(xlDown).Row
Dim c As Range
For i = d To 1 Step -1
aMove = Val(Cells(i, 1))
If aMove > 0 Then
Range(Cells(i, 1), Cells(i, aMove)).Insert shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
End If
Next
End Sub
Quite a few ways to do this, but by using the number in columnA to define the amount of cells to insert you can do a second loop like so:
Private Sub CommandButton1_Click()
Dim x, d, i As Integer
With ActiveSheet
d = .Range("A:A").End(xlDown).Row
For x = 2 To d
i = .Cells(x, 1).Value
For a = 1 To i
.Cells(x, 1).Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
Next a
Next x
End With
End Sub

excel vba - add table column with date based on adjacent cell that includes date and time

I have an excel table ("Table1") with 4 total columns. The 3rd and 4th column contain 'clock in' and 'clock out' information formatted to show date and time. For example :
6/3/2016 10:54:52 AM
I would like to do two things here...first, I want to create a new, 3rd column that just reads the date, formatted "d-mmm". This should match the date found in what would now be column 4.
The second thing I would like to do is take the date portion of text out of what would now be columns 4 and 5. So at the end, an example row of data might read as follows (columns 3:5):
C, D, E
7-Jun, 10:54:52 AM, 4:59:44 AM
Here is what I have so far for code:
Sub test()
Dim currentSht As Worksheet
Dim lst As ListObject
Set curretnSht = ActiveWorkbook.Sheets(1)
Set lst = currentSht.ListObjects("Table1")
lst.ListColumns.Add Position:=3
'Not really sure how to do the rest
End Sub
That's not the Excel way. Dates are numbers 0 represents 1/1/1900. Add 1 to it and you get the next day the value of an hour is 1/24 .
The biggest problem of your approach is Excel you stop editing the cell Excel evaluate the cells value. It'll still look like 7 - Jun but Excel changes the cells format and the cells value to be 7 - Jun of this your 6/7/216. It's best to have all the cells equal the same date. Just change the cells formatting to display the results that you want. If you need to calculate the Month use the a WorkSheet Function to do so. =Month(A1)
Try this:
Sub Demo()
Range("C1").EntireColumn.Insert '-->insert column
Range("D:D").Copy Destination:=Range("C1") '-->copy column 4 to column 3
Range("C:C").NumberFormat = "d-mmm" '-->format column 3
Range("D:E").NumberFormat = "h:mm:ss AM/PM" '-->format column 4 and 5
End Sub
Even this will work:
Sub Demo()
Dim currentSht As Worksheet
Dim lastRow As Long
Set currentSht = ActiveWorkbook.Sheets("Sheet1")
lastRow = currentSht.Cells(Rows.Count, "C").End(xlUp).Row '-->get last row with data
currentSht.Range("C1").EntireColumn.Insert '-->insert column
currentSht.Range("C1:C" & lastRow) = currentSht.Range("D1:D" & lastRow).Value '-->copy column 4 to column 3
currentSht.Range("C1:C" & lastRow).NumberFormat = "d-mmm" '-->format column 3
currentSht.Range("D1:E" & lastRow).NumberFormat = "h:mm:ss AM/PM" '-->format column 4 and 5
End Sub
This meets your specs:
Sub InsertColumnAndFormatDates()
Columns("C:C").Copy
Selection.Insert Shift:=xlToRight
Application.CutCopyMode = False
Columns("C").NumberFormat = "d-mmm"
Columns("D:E").NumberFormat = "h:mm:ss AM/PM"
End Sub

how to import 2 row from txt or EXCEL into the same ROW in SQL server

I need to extract information from a page I have access to.
Just in this module, I have no means to export, but just to copying and pasting the information
Looks like this in the same l
1. MANUF MODEL YEAR MFG SERIAL REG OS DATE DESC LISTED1. YEAR DLV
2. monster 4r25 1988 23547248 Waka001 7/23/2012 For sale 7/22/20092. 1989
3. FORD 12SE 1994 6262552 DBZRLZ0 7/26/2012 For sale 7/9/20093. 1994
I'm getting my data in rows, but the year mfg and year dlv is in 2 rows within one row (or 2 rows in the same field). When pasted on excel it makes 2 rows first with all the data in the row including year mng and a second row just for year dlv (in the same column).
I can parse this information in excel by adding extra column and coping that extra field and deleting blanks and so on. But I want to omit the excel part and import this from a TXT file which when pasted creates 2 rows per row as well and using tabs as delimiter (like txt text tab delimited).
When I import with bulk insert, it imports twice as much rows, but I can't imagine a way to parse this second row into a new column.
Can someone help with this? In t-sql (every row has only one row of info, but in the column year mfg /year dlv, comes with two rows).
Or point me on what to read or which would be a better approach? Maybe importing 2 rows at once ETC.
You can import the data set from the text file into a temp table including the blank lines. This will give you a data set in SQL with 2 types of records. 1. Records that have all data except delivery date. 2. Records that have only delivery dates and no other fields. (Add a unique auto increment key)
Because the related records will be one record apart, Record N and Records N+1 are actually the same record.
Then a select query Joining the temp table to its self by RecID = RecId+1 will give a complete record with all fields
SELECT * FROM tmpTable AS MainRecord INNER JOIN tmpTable AS MissingField ON MainRecord.RecId = MissingField.RecId +1
From this dataset you can instert into your main data.
Do you know how to use VBA? You can run this code (FixData()) in Excel before you use it in TSQL so it fixes the extra row problem. Hope this helps
Option Explicit
Public Sub FixData()
Dim ws As Excel.Worksheet
Dim iCurRow As Long
Dim iLastRow As Long
Set ws = ActiveSheet
iLastRow = ws.Cells.SpecialCells(xlCellTypeLastCell).Row
' move through the spreadsheet from bottom to top
For iCurRow = iLastRow To 1 Step -1
If (isCurrentRowMessedUp(ws, iCurRow) = True) Then
Call AppendDataToPreviousRow(ws, iCurRow)
' delete the row since we moved the data out of there
ws.Rows(iCurRow).EntireRow.Delete
End If
Next
End Sub
Private Sub AppendDataToPreviousRow(ByRef ws As Excel.Worksheet, ByVal currentRow As Long)
Dim firstCellInRow As Excel.Range
Dim lastCellInRow As Excel.Range
Dim previousRowRangeToPaste As Excel.Range
' check if first column has data in it, otherwise find the first column that has data
If (ws.Cells(currentRow, 1).Value = vbNullString) Then
Set firstCellInRow = ws.Cells(currentRow, 1).End(xlToRight)
Else
Set firstCellInRow = ws.Cells(currentRow, 1)
End If
Set lastCellInRow = ws.Cells(currentRow, ws.Columns.Count).End(xlToLeft)
Set previousRowRangeToPaste = ws.Cells(currentRow - 1, getNextColumnAvailableInPreviousRow(ws, currentRow))
ws.Range(firstCellInRow, lastCellInRow).Cut previousRowRangeToPaste
End Sub
Private Function isCurrentRowMessedUp(ByRef ws As Excel.Worksheet, ByVal currentRow As Long) As Boolean
Dim cellCountInRow As Long
Dim firstCellInRow As Excel.Range
Dim lastCellInRow As Excel.Range
Set firstCellInRow = ws.Cells(currentRow, 1)
Set lastCellInRow = ws.Cells(currentRow, ws.Columns.Count).End(xlToLeft)
cellCountInRow = Application.WorksheetFunction.CountA(ws.Range(firstCellInRow, lastCellInRow))
If (cellCountInRow <= 1) Then
isCurrentRowMessedUp = True
Else
isCurrentRowMessedUp = False
End If
End Function
Private Function getLastColumnInPreviousRow(ByRef ws As Excel.Worksheet, ByVal currentRow As Long) As Long
Dim rng As Excel.Range
Set rng = ws.Cells(currentRow - 1, 1).End(xlToRight)
getLastColumnInPreviousRow = rng.Column
End Function
Private Function getNextColumnAvailableInPreviousRow(ByRef ws As Excel.Worksheet, ByVal currentRow As Long) As Long
getNextColumnAvailableInPreviousRow = getLastColumnInPreviousRow(ws, currentRow) + 1
End Function
you can use SQL Server Integration Service (SSIS) for convert data from any source data such as excel to any destination data such as SQL Server