Fill in the blanks (1 Viewer)

thenoisydrum

Registered User.
Local time
Today, 10:27
Joined
Jul 26, 2012
Messages
51
Hi all,
I have found a handful of instances on the web where people have asked about this and I even found what appears to be a solution at https://sfmagazine.com/post-entry/october-2015-access-fill-down/
However I cannot get it to work........ This is an example of my data;

Capture.JPG


Does anybody know how I can fill in the blank cells in MS Access?
I have a Sage .csv output report that has this type of structure to it. I'm currently using Excel to convert it and along with other things, fill in the blanks by doing the Go To/Special/Blanks etc (I'm sure you are all familiar with this)

What I want to do is import the report into a database and do all of the formatting in there. I thought I may be able to do something along the lines of adding an AutoNumber ID to give each row a reference. Maybe then and AutoNumber ID+1 to a copy of the table. That would enable me to update to the cell above but wouldn't quite do the trick

Does anybody have a solution please?

Thanks

Drum
 

Attachments

  • Capture.JPG
    Capture.JPG
    24.9 KB · Views: 160

MajP

You've got your good things, and you've got mine.
Local time
Today, 05:27
Joined
May 21, 2018
Messages
8,516
That would be easy to read the recordset and write in the missing numbers assuming it imports correctly. Do you have a test csv we can see.
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 05:27
Joined
May 21, 2018
Messages
8,516
Code:
Public Sub FillBlanks()
  Const TblName = "[tblAccounts]"
  Const AcctField = "[Account Number]"
  Dim rs As DAO.Recordset
  Dim oldAccountNumber As String
  Set rs = CurrentDb.OpenRecordset("select " & AcctField & " FROM " & TblName)
  'If there is a field like a date stamp to keep sorted properly add that to the select statement
  oldAccountNumber = rs.Fields(AcctField)
  Do While Not rs.EOF
    If Trim(rs.Fields(AcctField) & " ") = "" Then
      rs.Edit
        rs.Fields(AcctField) = oldAccountNumber
      rs.Update
    Else
      oldAccountNumber = rs.Fields(AcctField)
    End If
    rs.MoveNext
  Loop
End Sub
Works for me. Change tblName and AcctField constants as needed. If there is a field that naturally sorts this table then sort by that field. If not add an autonumber field. It may work without a sort field, but it is not guarnateed
Change the code to
Set rs = CurrentDb.OpenRecordset("select " & AcctField & " FROM " & TblName & " ORDER BY YourFieldName")
 

thenoisydrum

Registered User.
Local time
Today, 10:27
Joined
Jul 26, 2012
Messages
51
Thanks for your response. Do I literally copy and paste your code into a macro, changing the table and field names?
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 05:27
Joined
May 21, 2018
Messages
8,516
Yes. Here is a more generic version. It solves the problem shown in the link where you have multiple fields.
BalanceSheetBackup

IDGroup 1Group 2Group 3AccountAmount
1​
AssetsAssetsCurrent AssetsCash
$414,527.00​
2​
Accounts Receiveable, net
$482,995.00​
3​
Raw Materials Inventory
$99,663.00​
4​
Finished Goods Inventory
$128,285.00​
5​
Property, Plant and EquipmentBuilding
$1,500,000.00​
6​
Equipment
$1,687,000.00​
7​
Accumulated Depr - Building and Equipment
($937,500.00)​
8​
Liabilities and Stockholder's EquityLiabilitiesCurrent LiabilitiesAccounts Payable
$161,400.00​
9​
Interest Payable
$0.00​
10​
Income Tax Payable
$145,155.00​
11​
Long Term LiabilitiesBonds Payable
$997,600.00​
12​
Loans Payable
$0.00​
13​
Stockholders' EquityStockholders' EquityCommon Stock (100,000 shares outstanding)
$1,000,000.00​
14​
Retained Earnings
$1,070,815.00​

Here is the code to use
Code:
' Procedure Name: AccessFillDown
' Purpose: Mimics Excel FillDown
' Procedure Kind: Sub
' Procedure Access: Public
' Parameter TableName (String): Name of the table
' Parameter SortFieldName (String): Field on which to sort to ensure data is in the correct order
' Parameter FieldNames (Variant()): Array of just the fields to fill-in
' Author: MajP
' Date: 5/24/2020
' ----------------------------------------------------------------
Public Sub AccessFillDown(TableName As String, SortFieldName As String, ParamArray FieldNames() As Variant)
  On Error GoTo AccessFillDown_Error
  Dim rs As DAO.Recordset
  Dim fld As DAO.Field
  Dim fieldName As String
  Dim OldValue As Variant
  Dim i As Integer
 
  Set rs = CurrentDb.OpenRecordset("Select * from " & TableName & " ORDER BY " & SortFieldName)
 
  For i = 0 To UBound(FieldNames)
    fieldName = FieldNames(i)
    rs.MoveFirst
    Set fld = rs.Fields(fieldName)
    'Assumes that every field to fill down has a value in first row
    OldValue = fld.Value
    Do While Not rs.EOF
        If Trim(fld.Value & " ") = "" Then
          rs.Edit
            fld.Value = OldValue
          rs.Update
        Else
          OldValue = fld.Value
        End If
        rs.MoveNext
    Loop
  Next i
   Exit Sub
AccessFillDown_Error:
    MsgBox "Error " & Err.Number & " (" & Err.Description & ") in procedure AccessFillDown, line " & Erl & "."
End Sub

To use. Go into the vba window and insert a new "Standard Module" not a class module. In the module drop the code. Then drop this code

Code:
Public Sub TestFillDown()
  AccessFillDown "[Balance Sheet]", "ID", "[Group 1]", "[Group 2]", "[Group 3]"
End Sub

The first argument should be the name of your table. [] are needed when names have spaces. The second is your sort field name. The rest are the names of any fields to fill in.

In VBA hit the run button or pick "Run". Here is my output. A lot easier in my opinion and should work on any table with any amount of fields. As long as there are values in the first row.
Balance Sheet

IDGroup 1Group 2Group 3AccountAmount
1​
AssetsAssetsCurrent AssetsCash
$414,527.00​
2​
AssetsAssetsCurrent AssetsAccounts Receiveable, net
$482,995.00​
3​
AssetsAssetsCurrent AssetsRaw Materials Inventory
$99,663.00​
4​
AssetsAssetsCurrent AssetsFinished Goods Inventory
$128,285.00​
5​
AssetsAssetsProperty, Plant and EquipmentBuilding
$1,500,000.00​
6​
AssetsAssetsProperty, Plant and EquipmentEquipment
$1,687,000.00​
7​
AssetsAssetsProperty, Plant and EquipmentAccumulated Depr - Building and Equipment
($937,500.00)​
8​
Liabilities and Stockholder's EquityLiabilitiesCurrent LiabilitiesAccounts Payable
$161,400.00​
9​
Liabilities and Stockholder's EquityLiabilitiesCurrent LiabilitiesInterest Payable
$0.00​
10​
Liabilities and Stockholder's EquityLiabilitiesCurrent LiabilitiesIncome Tax Payable
$145,155.00​
11​
Liabilities and Stockholder's EquityLiabilitiesLong Term LiabilitiesBonds Payable
$997,600.00​
12​
Liabilities and Stockholder's EquityLiabilitiesLong Term LiabilitiesLoans Payable
$0.00​
13​
Liabilities and Stockholder's EquityStockholders' EquityStockholders' EquityCommon Stock (100,000 shares outstanding)
$1,000,000.00​
14​
Liabilities and Stockholder's EquityStockholders' EquityStockholders' EquityRetained Earnings
$1,070,815.00​
 

onur_can

Active member
Local time
Today, 02:27
Joined
Oct 4, 2015
Messages
180
Hello
Why didn't you define the Account Number field as a mandatory field from the beginning?
 

Gasman

Enthusiastic Amateur
Local time
Today, 10:27
Joined
Sep 21, 2011
Messages
14,217
I would have thought the easiest option to start with would be to get the report output without the 'blank when duplicate' option.?
So go back to your source and ask for some decent output.
If then that is not possible, well MajP has solved you problem. Best not to have that problem in the first place.?
 
Last edited:

thenoisydrum

Registered User.
Local time
Today, 10:27
Joined
Jul 26, 2012
Messages
51
Yes. Here is a more generic version. It solves the problem shown in the link where you have multiple fields.
BalanceSheetBackup

IDGroup 1Group 2Group 3AccountAmount
1​
AssetsAssetsCurrent AssetsCash
$414,527.00​
2​
Accounts Receiveable, net
$482,995.00​
3​
Raw Materials Inventory
$99,663.00​
4​
Finished Goods Inventory
$128,285.00​
5​
Property, Plant and EquipmentBuilding
$1,500,000.00​
6​
Equipment
$1,687,000.00​
7​
Accumulated Depr - Building and Equipment
($937,500.00)​
8​
Liabilities and Stockholder's EquityLiabilitiesCurrent LiabilitiesAccounts Payable
$161,400.00​
9​
Interest Payable
$0.00​
10​
Income Tax Payable
$145,155.00​
11​
Long Term LiabilitiesBonds Payable
$997,600.00​
12​
Loans Payable
$0.00​
13​
Stockholders' EquityStockholders' EquityCommon Stock (100,000 shares outstanding)
$1,000,000.00​
14​
Retained Earnings
$1,070,815.00​

Here is the code to use
Code:
' Procedure Name: AccessFillDown
' Purpose: Mimics Excel FillDown
' Procedure Kind: Sub
' Procedure Access: Public
' Parameter TableName (String): Name of the table
' Parameter SortFieldName (String): Field on which to sort to ensure data is in the correct order
' Parameter FieldNames (Variant()): Array of just the fields to fill-in
' Author: MajP
' Date: 5/24/2020
' ----------------------------------------------------------------
Public Sub AccessFillDown(TableName As String, SortFieldName As String, ParamArray FieldNames() As Variant)
  On Error GoTo AccessFillDown_Error
  Dim rs As DAO.Recordset
  Dim fld As DAO.Field
  Dim fieldName As String
  Dim OldValue As Variant
  Dim i As Integer

  Set rs = CurrentDb.OpenRecordset("Select * from " & TableName & " ORDER BY " & SortFieldName)

  For i = 0 To UBound(FieldNames)
    fieldName = FieldNames(i)
    rs.MoveFirst
    Set fld = rs.Fields(fieldName)
    'Assumes that every field to fill down has a value in first row
    OldValue = fld.Value
    Do While Not rs.EOF
        If Trim(fld.Value & " ") = "" Then
          rs.Edit
            fld.Value = OldValue
          rs.Update
        Else
          OldValue = fld.Value
        End If
        rs.MoveNext
    Loop
  Next i
   Exit Sub
AccessFillDown_Error:
    MsgBox "Error " & Err.Number & " (" & Err.Description & ") in procedure AccessFillDown, line " & Erl & "."
End Sub

To use. Go into the vba window and insert a new "Standard Module" not a class module. In the module drop the code. Then drop this code

Code:
Public Sub TestFillDown()
  AccessFillDown "[Balance Sheet]", "ID", "[Group 1]", "[Group 2]", "[Group 3]"
End Sub

The first argument should be the name of your table. [] are needed when names have spaces. The second is your sort field name. The rest are the names of any fields to fill in.

In VBA hit the run button or pick "Run". Here is my output. A lot easier in my opinion and should work on any table with any amount of fields. As long as there are values in the first row.
Balance Sheet

IDGroup 1Group 2Group 3AccountAmount
1​
AssetsAssetsCurrent AssetsCash
$414,527.00​
2​
AssetsAssetsCurrent AssetsAccounts Receiveable, net
$482,995.00​
3​
AssetsAssetsCurrent AssetsRaw Materials Inventory
$99,663.00​
4​
AssetsAssetsCurrent AssetsFinished Goods Inventory
$128,285.00​
5​
AssetsAssetsProperty, Plant and EquipmentBuilding
$1,500,000.00​
6​
AssetsAssetsProperty, Plant and EquipmentEquipment
$1,687,000.00​
7​
AssetsAssetsProperty, Plant and EquipmentAccumulated Depr - Building and Equipment
($937,500.00)​
8​
Liabilities and Stockholder's EquityLiabilitiesCurrent LiabilitiesAccounts Payable
$161,400.00​
9​
Liabilities and Stockholder's EquityLiabilitiesCurrent LiabilitiesInterest Payable
$0.00​
10​
Liabilities and Stockholder's EquityLiabilitiesCurrent LiabilitiesIncome Tax Payable
$145,155.00​
11​
Liabilities and Stockholder's EquityLiabilitiesLong Term LiabilitiesBonds Payable
$997,600.00​
12​
Liabilities and Stockholder's EquityLiabilitiesLong Term LiabilitiesLoans Payable
$0.00​
13​
Liabilities and Stockholder's EquityStockholders' EquityStockholders' EquityCommon Stock (100,000 shares outstanding)
$1,000,000.00​
14​
Liabilities and Stockholder's EquityStockholders' EquityStockholders' EquityRetained Earnings
$1,070,815.00​

Not sure what I'm doing wrong here.
This is my table;

Capture1.JPG


.... here is the error that I get;

Capture.JPG


What am I doing wrong here?

Thanks in advance

Drum
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 05:27
Joined
May 21, 2018
Messages
8,516
The intent was not to change the code, but change the value of the constants only. That is the value of using constants as placeholders.
So just change the value of the constants like you did, but leave the rest of the code as is.

This line is looking for the constants AcctField and TblName, which are like variables but can only be set once. So keep this line as is.
Set rs = CurrentDb.OpenRecordset("select " & AcctField & " FROM " & TblName)
 

Pat Hartman

Super Moderator
Staff member
Local time
Today, 05:27
Joined
Feb 19, 2002
Messages
43,196
One thing to keep in mind is that this method works IF and ONLY IF, you have a unique identifier that will sort the recordset into the order that will cause the blanks to be filled with the correct information.

In relational databases, tables and queries are unordered sets. If you do not specifically sort them, you cannot depend on the sequence in which records will be returned. That would leave you with the only option being to write the macro to fill in the gaps in Excel which is NOT a relational database and which will always retain physical record order UNLESS you sort.
 

Users who are viewing this thread

Top Bottom